From 05d6f782a9db4bedb05e0855e9b9e5c227e2cbef Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 9 Jul 2024 18:33:38 +0530 Subject: [PATCH 001/112] Added Rosenbrock methods --- .../test/runtests.jl | 2 +- lib/OrdinaryDiffEqRosenbrock/Project.toml | 20 ++ .../src/OrdinaryDiffEqRosenbrock.jl | 30 +++ lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl | 52 +++++ .../src/algorithms.jl | 208 +++++++++++++++++ .../src}/generic_rosenbrock.jl | 2 +- .../src/integrator_interface.jl | 34 +++ .../src/integrator_utils.jl | 32 +++ .../src/interp_func.jl | 19 ++ .../src}/rosenbrock_caches.jl | 2 +- .../src}/rosenbrock_interpolants.jl | 2 +- .../src}/rosenbrock_perform_step.jl | 0 .../src}/rosenbrock_tableaus.jl | 2 +- .../src}/stiff_addsteps.jl | 0 .../test}/ode_rosenbrock_tests.jl | 2 +- lib/OrdinaryDiffEqRosenbrock/test/runtests.jl | 3 + src/OrdinaryDiffEq.jl | 23 +- src/alg_utils.jl | 51 ----- src/algorithms.jl | 209 ------------------ src/doc_utils.jl | 54 ++--- src/integrators/integrator_interface.jl | 34 --- src/integrators/integrator_utils.jl | 33 --- src/interp_func.jl | 19 -- test/runtests.jl | 5 +- 24 files changed, 444 insertions(+), 394 deletions(-) create mode 100644 lib/OrdinaryDiffEqRosenbrock/Project.toml create mode 100644 lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl create mode 100644 lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl rename {src => lib/OrdinaryDiffEqRosenbrock/src}/generic_rosenbrock.jl (99%) create mode 100644 lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl create mode 100644 lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl create mode 100644 lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl rename {src/caches => lib/OrdinaryDiffEqRosenbrock/src}/rosenbrock_caches.jl (99%) rename {src/dense => lib/OrdinaryDiffEqRosenbrock/src}/rosenbrock_interpolants.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqRosenbrock/src}/rosenbrock_perform_step.jl (100%) rename {src/tableaus => lib/OrdinaryDiffEqRosenbrock/src}/rosenbrock_tableaus.jl (99%) rename {src/dense => lib/OrdinaryDiffEqRosenbrock/src}/stiff_addsteps.jl (100%) rename {test/algconvergence => lib/OrdinaryDiffEqRosenbrock/test}/ode_rosenbrock_tests.jl (99%) create mode 100644 lib/OrdinaryDiffEqRosenbrock/test/runtests.jl diff --git a/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl b/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl index 7225e9390c..6d0407a60b 100644 --- a/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl +++ b/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl @@ -1,3 +1,3 @@ using SafeTestsets -@time @safetestset "Low Storage RK Tests" include("ode_low_storage_rk_tests.jl") +@time @safetestset "Low Storage RK Tests" include("ode_low_storage_rk_tests.jl") \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/Project.toml b/lib/OrdinaryDiffEqRosenbrock/Project.toml new file mode 100644 index 0000000000..422bbff248 --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/Project.toml @@ -0,0 +1,20 @@ +name = "OrdinaryDiffEqRosenbrock" +uuid = "849cf443-90a5-45fe-9245-010b279924ce" +authors = ["ParamThakkar123 "] +version = "1.0.0" + +[deps] +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +julia = "1.10" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl new file mode 100644 index 0000000000..10fdc4c5fa --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl @@ -0,0 +1,30 @@ +module OrdinaryDiffEqRosenbrock + +import OrdinaryDiffEq: OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, OrdinaryDiffEqRosenbrockAlgorithm, rosenbrock_docstring, + rosenbrock_wanner_docstring, + OrdinaryDiffEqMutableCache, alg_order, alg_adaptive_order, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqAdaptiveAlgorithm +using DiffEqBase, MuladdMacro + +include("algorithms.jl") +include("alg_utils.jl") +include("rosenbrock_tableaus.jl") +include("generic_rosenbrock.jl") +include("rosenbrock_caches.jl") +include("integrator_interface.jl") +include("integrator_utils.jl") +include("interp_func.jl") +include("stiff_addsteps.jl") +include("rosenbrock_interpolants.jl") +include("rosenbrock_tableaus.jl") + +export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, + Ros4LStab, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2, + Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, + RosenbrockW6S4OS, ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, + ROS3PRL2, ROK4a, + ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 + +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl b/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl new file mode 100644 index 0000000000..13edd290e7 --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl @@ -0,0 +1,52 @@ +alg_order(alg::ROS2) = 2 +alg_order(alg::ROS2PR) = 2 +alg_order(alg::ROS2S) = 2 +alg_order(alg::ROS3) = 3 +alg_order(alg::ROS3PR) = 3 +alg_order(alg::Scholz4_7) = 3 +alg_order(alg::Rosenbrock23) = 2 +alg_order(alg::Rodas23W) = 3 +alg_order(alg::Rosenbrock32) = 3 +alg_order(alg::ROS3P) = 3 +alg_order(alg::Rodas3) = 3 +alg_order(alg::Rodas3P) = 3 +alg_order(alg::ROS34PW1a) = 3 +alg_order(alg::ROS34PW1b) = 3 +alg_order(alg::ROS34PW2) = 3 +alg_order(alg::ROS34PW3) = 4 +alg_order(alg::ROS34PRw) = 3 +alg_order(alg::ROS3PRL) = 3 +alg_order(alg::ROS3PRL2) = 3 +alg_order(alg::ROK4a) = 4 +alg_order(alg::RosShamp4) = 4 +alg_order(alg::Veldd4) = 4 +alg_order(alg::Velds4) = 4 +alg_order(alg::GRK4T) = 4 +alg_order(alg::GRK4A) = 4 +alg_order(alg::Ros4LStab) = 4 +alg_order(alg::RosenbrockW6S4OS) = 4 +alg_order(alg::Rodas4) = 4 +alg_order(alg::Rodas42) = 4 +alg_order(alg::Rodas4P) = 4 +alg_order(alg::Rodas4P2) = 4 +alg_order(alg::Rodas5) = 5 +alg_order(alg::Rodas5P) = 5 +alg_order(alg::Rodas5Pr) = 5 +alg_order(alg::Rodas5Pe) = 5 + +isWmethod(alg::Rosenbrock23) = true +isWmethod(alg::Rosenbrock32) = true +isWmethod(alg::Rodas23W) = true +isWmethod(alg::ROS2S) = true +isWmethod(alg::ROS34PW1a) = true +isWmethod(alg::ROS34PW1b) = true +isWmethod(alg::ROS34PW2) = true +isWmethod(alg::ROS34PW3) = true +isWmethod(alg::ROS34PRw) = true +isWmethod(alg::ROK4a) = true +isWmethod(alg::RosenbrockW6S4OS) = true + +alg_adaptive_order(alg::Rosenbrock23) = 3 +alg_adaptive_order(alg::Rosenbrock32) = 2 + +is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl b/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl new file mode 100644 index 0000000000..88f7520646 --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl @@ -0,0 +1,208 @@ +################################################################################ + +# Rosenbrock Methods + +#= +#### Rosenbrock23, Rosenbrock32, ode23s, ModifiedRosenbrockIntegrator + +- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of +Scientific Computing, 18 (1), pp. 1-22. + +#### ROS2 + +- J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems + https://doi.org/10.1137/S1064827597326651 + +#### ROS3P + +- Lang, J. & Verwer, ROS3P—An Accurate Third-Order Rosenbrock Solver Designed for + Parabolic Problems J. BIT Numerical Mathematics (2001) 41: 731. doi:10.1023/A:1021900219772 + +#### ROS3, Rodas3, Ros4LStab, Rodas4, Rodas42 + +- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and + differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) + +#### ROS2PR, ROS2S, ROS3PR, Scholz4_7 +-Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 + +#### RosShamp4 + +- L. F. Shampine, Implementation of Rosenbrock Methods, ACM Transactions on + Mathematical Software (TOMS), 8: 2, 93-113. doi:10.1145/355993.355994 + +#### Veldd4, Velds4 + +- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. + doi:10.1007/BF02243574 + +#### GRK4T, GRK4A + +- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control + for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 + +#### Rodas23W, Rodas3P + +- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate for dense output and Julia implementation, + in progress + +#### Rodas4P + +- Steinebach G. Order-reduction of ROW-methods for DAEs and method of lines + applications. Preprint-Nr. 1741, FB Mathematik, TH Darmstadt; 1995. + +#### Rodas4P2 +- Steinebach G. (2020) Improvement of Rosenbrock-Wanner Method RODASP. + In: Reis T., Grundel S., Schoeps S. (eds) Progress in Differential-Algebraic Equations II. + Differential-Algebraic Equations Forum. Springer, Cham. https://doi.org/10.1007/978-3-030-53905-4_6 + +#### Rodas5 +- Di Marzo G. RODAS5(4) – Méthodes de Rosenbrock d’ordre 5(4) adaptées aux problemes +différentiels-algébriques. MSc mathematics thesis, Faculty of Science, +University of Geneva, Switzerland. + +#### ROS34PRw +-Joachim Rang, Improved traditional Rosenbrock–Wanner methods for stiff ODEs and DAEs, + Journal of Computational and Applied Mathematics, + https://doi.org/10.1016/j.cam.2015.03.010 + +#### ROS3PRL, ROS3PRL2 +-Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 + +#### ROK4a +- Tranquilli, Paul and Sandu, Adrian (2014): + Rosenbrock--Krylov Methods for Large Systems of Differential Equations + https://doi.org/10.1137/130923336 + +#### Rodas5P +- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks within the Julia Differential Equations package. + In: BIT Numerical Mathematics, 63(2), 2023 + + #### Rodas23W, Rodas3P, Rodas5Pe, Rodas5Pr +- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - + Preprint 2024 + https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf + +=# + +for Alg in [ + :ROS2, + :ROS2PR, + :ROS2S, + :ROS3, + :ROS3PR, + :Scholz4_7, + :ROS34PW1a, + :ROS34PW1b, + :ROS34PW2, + :ROS34PW3, + :ROS34PRw, + :ROS3PRL, + :ROS3PRL2, + :ROK4a, + :RosShamp4, + :Veldd4, + :Velds4, + :GRK4T, + :GRK4A, + :Ros4LStab] + @eval begin + struct $Alg{CS, AD, F, P, FDT, ST, CJ} <: + OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + end + function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, linsolve = nothing, precs = DEFAULT_PRECS) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + precs) + end + end + + @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 +end + +# for Rosenbrock methods with step_limiter +for Alg in [ + :Rosenbrock23, + :Rosenbrock32, + :ROS3P, + :Rodas3, + :Rodas23W, + :Rodas3P, + :Rodas4, + :Rodas42, + :Rodas4P, + :Rodas4P2, + :Rodas5, + :Rodas5P, + :Rodas5Pe, + :Rodas5Pr] + @eval begin + struct $Alg{CS, AD, F, P, FDT, ST, CJ, StepLimiter, StageLimiter} <: + OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + step_limiter!::StepLimiter + stage_limiter!::StageLimiter + end + function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, linsolve = nothing, + precs = DEFAULT_PRECS, step_limiter! = trivial_limiter!, + stage_limiter! = trivial_limiter!) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!), + typeof(stage_limiter!)}(linsolve, precs, step_limiter!, + stage_limiter!) + end + end + + @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 +end +struct GeneralRosenbrock{CS, AD, F, ST, CJ, TabType} <: + OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, Val{:forward}, ST, CJ} + tableau::TabType + factorization::F +end + +function GeneralRosenbrock(; chunk_size = Val{0}(), autodiff = true, + standardtag = Val{true}(), concrete_jac = nothing, + factorization = lu!, tableau = ROSENBROCK_DEFAULT_TABLEAU) + GeneralRosenbrock{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(factorization), + _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(tableau)}(tableau, + factorization) +end + +@doc rosenbrock_wanner_docstring( + """ + A 4th order L-stable Rosenbrock-W method (fixed step only). + """, + "RosenbrockW6S4OS", + references = """ + https://doi.org/10.1016/j.cam.2009.09.017 + """) +struct RosenbrockW6S4OS{CS, AD, F, P, FDT, ST, CJ} <: + OrdinaryDiffEqRosenbrockAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P +end +function RosenbrockW6S4OS(; chunk_size = Val{0}(), autodiff = true, + standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:central}, + linsolve = nothing, + precs = DEFAULT_PRECS) + RosenbrockW6S4OS{_unwrap_val(chunk_size), + _unwrap_val(autodiff), typeof(linsolve), typeof(precs), diff_type, + _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, + precs) +end diff --git a/src/generic_rosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl similarity index 99% rename from src/generic_rosenbrock.jl rename to lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl index 32330c27e1..9cf7420395 100644 --- a/src/generic_rosenbrock.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl @@ -1807,4 +1807,4 @@ You need to change respective places in this file. `gen_initialize()` and special step expressions in macro definitions 2. `caches/rosenbrock_caches.jl` -> `gen_algcache()`, `gen_cache_struct()` 3. `tableaus/rosenbrock_tableaus.jl` -> `gen_tableau_struct()` and `gen_tableau()` -=========================================================================================# +=========================================================================================# \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl b/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl new file mode 100644 index 0000000000..d797e899b6 --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl @@ -0,0 +1,34 @@ +@inline function DiffEqBase.get_du!(out, integrator::ODEIntegrator) + integrator.cache isa FunctionMapCache || + integrator.cache isa FunctionMapConstantCache && + error("Derivatives are not defined for this stepper.") + if integrator.cache isa FunctionMapCache + out .= integrator.cache.tmp + else + return if isdefined(integrator, :fsallast) && + !(integrator.alg isa + Union{Rosenbrock23, Rosenbrock32, Rodas23W, + Rodas3P, Rodas4, Rodas4P, Rodas4P2, Rodas5, + Rodas5P, Rodas5Pe, Rodas5Pr}) + # Special stiff interpolations do not store the right value in fsallast + out .= integrator.fsallast + else + integrator(out, integrator.t, Val{1}) + end + end +end + +@inline function DiffEqBase.get_tmp_cache(integrator, + alg::OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, + cache::OrdinaryDiffEqMutableCache) + (cache.tmp, cache.linsolve_tmp) +end + +function resize_non_user_cache!(integrator::ODEIntegrator, + cache::RosenbrockMutableCache, i) + cache.J = similar(cache.J, i, i) + cache.W = similar(cache.W, i, i) + resize_jac_config!(cache.jac_config, i) + resize_grad_config!(cache.grad_config, i) + nothing +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl b/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl new file mode 100644 index 0000000000..3131073f94 --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl @@ -0,0 +1,32 @@ +function apply_step!(integrator) + update_uprev!(integrator) + + #Update dt if adaptive or if fixed and the dt is allowed to change + if integrator.opts.adaptive || integrator.dtchangeable + integrator.dt = integrator.dtpropose + elseif integrator.dt != integrator.dtpropose && !integrator.dtchangeable + error("The current setup does not allow for changing dt.") + end + + # Update fsal if needed + if has_discontinuity(integrator) && + first_discontinuity(integrator) == integrator.tdir * integrator.t + handle_discontinuities!(integrator) + get_current_isfsal(integrator.alg, integrator.cache) && reset_fsal!(integrator) + elseif all_fsal(integrator.alg, integrator.cache) || + get_current_isfsal(integrator.alg, integrator.cache) + if integrator.reeval_fsal || integrator.u_modified || + (integrator.alg isa DP8 && !integrator.opts.calck) || + (integrator.alg isa Union{Rosenbrock23, Rosenbrock32} && + !integrator.opts.adaptive) + reset_fsal!(integrator) + else # Do not reeval_fsal, instead copyto! over + if isinplace(integrator.sol.prob) + recursivecopy!(integrator.fsalfirst, integrator.fsallast) + else + integrator.fsalfirst = integrator.fsallast + end + end + end + return nothing +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl b/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl new file mode 100644 index 0000000000..fe7a5e935f --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl @@ -0,0 +1,19 @@ +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Rosenbrock23ConstantCache, + Rosenbrock32ConstantCache, + Rosenbrock23Cache, + Rosenbrock32Cache}} + dense ? "specialized 2nd order \"free\" stiffness-aware interpolation" : + "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Rosenbrock5ConstantCache, + Rosenbrock5Cache}} + dense ? "specialized 4rd order \"free\" stiffness-aware interpolation" : + "1st order linear" +end diff --git a/src/caches/rosenbrock_caches.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl similarity index 99% rename from src/caches/rosenbrock_caches.jl rename to lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl index e2eb013809..6076fe7dbb 100644 --- a/src/caches/rosenbrock_caches.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl @@ -1140,4 +1140,4 @@ end ### RosenbrockW6S4O -@RosenbrockW6S4OS(:cache) +@RosenbrockW6S4OS(:cache) \ No newline at end of file diff --git a/src/dense/rosenbrock_interpolants.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl similarity index 99% rename from src/dense/rosenbrock_interpolants.jl rename to lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl index 6f50205cf1..e691619b70 100644 --- a/src/dense/rosenbrock_interpolants.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl @@ -364,4 +364,4 @@ end @views @.. broadcast=false out=(-6 * k[2][idxs] + 6 * k[3][idxs] - 24 * Θ * k[3][idxs]) / dt^3 out -end +end \ No newline at end of file diff --git a/src/perform_step/rosenbrock_perform_step.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl similarity index 100% rename from src/perform_step/rosenbrock_perform_step.jl rename to lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl diff --git a/src/tableaus/rosenbrock_tableaus.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl similarity index 99% rename from src/tableaus/rosenbrock_tableaus.jl rename to lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl index 493c67111a..66dc620871 100644 --- a/src/tableaus/rosenbrock_tableaus.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl @@ -830,4 +830,4 @@ beta3 = 6.8619167645278386e-2 beta4 = 0.8289547562599182 beta5 = 7.9630136489868164e-2 alpha64 = -0.2076823627400282 -=# +=# \ No newline at end of file diff --git a/src/dense/stiff_addsteps.jl b/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl similarity index 100% rename from src/dense/stiff_addsteps.jl rename to lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl diff --git a/test/algconvergence/ode_rosenbrock_tests.jl b/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl similarity index 99% rename from test/algconvergence/ode_rosenbrock_tests.jl rename to lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl index e71ec00355..ce876ae507 100644 --- a/test/algconvergence/ode_rosenbrock_tests.jl +++ b/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl @@ -703,4 +703,4 @@ end # Primarily to check that the Jacobian is being updated correctly as t changes. sim = test_convergence(dts, prob, Rodas3(linsolve = LinearSolve.KrylovJL())) @test sim.𝒪est[:final]≈3 atol=testTol -end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/test/runtests.jl b/lib/OrdinaryDiffEqRosenbrock/test/runtests.jl new file mode 100644 index 0000000000..75f8efa4f4 --- /dev/null +++ b/lib/OrdinaryDiffEqRosenbrock/test/runtests.jl @@ -0,0 +1,3 @@ +using SafeTestsets + +@time @safetestset "Rosenbrock Tests" include("ode_rosenbrock_tests.jl") \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 8eabc4c6ee..ad9cfc295e 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -144,8 +144,6 @@ include("nlsolve/nlsolve.jl") include("nlsolve/functional.jl") include("nlsolve/newton.jl") -include("generic_rosenbrock.jl") - include("caches/basic_caches.jl") include("caches/low_order_rk_caches.jl") include("caches/high_order_rk_caches.jl") @@ -154,7 +152,6 @@ include("caches/firk_caches.jl") include("caches/kencarp_kvaerno_caches.jl") include("caches/linear_caches.jl") include("caches/linear_nonlinear_caches.jl") -include("caches/rosenbrock_caches.jl") include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") include("caches/bdf_caches.jl") @@ -165,7 +162,6 @@ include("caches/qprk_caches.jl") include("tableaus/low_order_rk_tableaus.jl") include("tableaus/high_order_rk_tableaus.jl") -include("tableaus/rosenbrock_tableaus.jl") include("tableaus/sdirk_tableaus.jl") include("tableaus/firk_tableaus.jl") include("tableaus/qprk_tableaus.jl") @@ -189,7 +185,6 @@ include("perform_step/high_order_rk_perform_step.jl") include("perform_step/sdirk_perform_step.jl") include("perform_step/kencarp_kvaerno_perform_step.jl") include("perform_step/firk_perform_step.jl") -include("perform_step/rosenbrock_perform_step.jl") include("perform_step/composite_perform_step.jl") include("perform_step/adams_bashforth_moulton_perform_step.jl") include("perform_step/nordsieck_perform_step.jl") @@ -201,8 +196,6 @@ include("perform_step/qprk_perform_step.jl") include("dense/generic_dense.jl") include("dense/interpolants.jl") -include("dense/rosenbrock_interpolants.jl") -include("dense/stiff_addsteps.jl") include("dense/low_order_rk_addsteps.jl") include("dense/high_order_rk_addsteps.jl") @@ -279,6 +272,15 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm +include("../lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl") +using ..OrdinaryDiffEqRosenbrock +export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, + Ros4LStab, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2, + Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, + RosenbrockW6S4OS, ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, + ROS3PRL2, ROK4a, + ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 + import PrecompileTools PrecompileTools.@compile_workload begin @@ -428,13 +430,6 @@ export MagnusMidpoint, LinearExponential, MagnusLeapfrog, LieEuler, CayleyEuler, MagnusGauss4, MagnusNC6, MagnusGL6, MagnusGL8, MagnusNC8, MagnusGL4, MagnusAdapt4, RKMK2, RKMK4, LieRK4, CG2, CG3, CG4a -export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, - Ros4LStab, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2, - Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, - RosenbrockW6S4OS, ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, - ROS3PRL2, ROK4a, - ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 - export LawsonEuler, NorsettEuler, ETD1, ETDRK2, ETDRK3, ETDRK4, HochOst4, Exp4, EPIRK4s3A, EPIRK4s3B, EPIRK5s3, EXPRB53s3, EPIRK5P1, EPIRK5P2, ETD2, Exprb32, Exprb43 diff --git a/src/alg_utils.jl b/src/alg_utils.jl index da79af736d..2fbde7a9e5 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -488,42 +488,6 @@ alg_order(alg::Hairer4) = 4 alg_order(alg::Hairer42) = 4 alg_order(alg::PFRK87) = 8 -alg_order(alg::ROS2) = 2 -alg_order(alg::ROS2PR) = 2 -alg_order(alg::ROS2S) = 2 -alg_order(alg::ROS3) = 3 -alg_order(alg::ROS3PR) = 3 -alg_order(alg::Scholz4_7) = 3 -alg_order(alg::Rosenbrock23) = 2 -alg_order(alg::Rodas23W) = 3 -alg_order(alg::Rosenbrock32) = 3 -alg_order(alg::ROS3P) = 3 -alg_order(alg::Rodas3) = 3 -alg_order(alg::Rodas3P) = 3 -alg_order(alg::ROS34PW1a) = 3 -alg_order(alg::ROS34PW1b) = 3 -alg_order(alg::ROS34PW2) = 3 -alg_order(alg::ROS34PW3) = 4 -alg_order(alg::ROS34PRw) = 3 -alg_order(alg::ROS3PRL) = 3 -alg_order(alg::ROS3PRL2) = 3 -alg_order(alg::ROK4a) = 4 -alg_order(alg::RosShamp4) = 4 -alg_order(alg::Veldd4) = 4 -alg_order(alg::Velds4) = 4 -alg_order(alg::GRK4T) = 4 -alg_order(alg::GRK4A) = 4 -alg_order(alg::Ros4LStab) = 4 -alg_order(alg::RosenbrockW6S4OS) = 4 -alg_order(alg::Rodas4) = 4 -alg_order(alg::Rodas42) = 4 -alg_order(alg::Rodas4P) = 4 -alg_order(alg::Rodas4P2) = 4 -alg_order(alg::Rodas5) = 5 -alg_order(alg::Rodas5P) = 5 -alg_order(alg::Rodas5Pr) = 5 -alg_order(alg::Rodas5Pe) = 5 - alg_order(alg::AB3) = 3 alg_order(alg::AB4) = 4 alg_order(alg::AB5) = 5 @@ -574,9 +538,6 @@ alg_maximum_order(alg::CompositeAlgorithm) = maximum(alg_order(x) for x in alg.a alg_adaptive_order(alg::ExplicitRK) = alg.tableau.adaptiveorder alg_adaptive_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = alg_order(alg) - 1 -alg_adaptive_order(alg::Rosenbrock23) = 3 -alg_adaptive_order(alg::Rosenbrock32) = 2 - alg_adaptive_order(alg::RadauIIA3) = 1 alg_adaptive_order(alg::RadauIIA5) = 3 @@ -738,17 +699,6 @@ isstandard(alg::OrdinaryDiffEqNewtonAdaptiveAlgorithm) = alg.controller === :Sta isstandard(alg::VCABM) = true isWmethod(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false -isWmethod(alg::Rosenbrock23) = true -isWmethod(alg::Rosenbrock32) = true -isWmethod(alg::Rodas23W) = true -isWmethod(alg::ROS2S) = true -isWmethod(alg::ROS34PW1a) = true -isWmethod(alg::ROS34PW1b) = true -isWmethod(alg::ROS34PW2) = true -isWmethod(alg::ROS34PW3) = true -isWmethod(alg::ROS34PRw) = true -isWmethod(alg::ROK4a) = true -isWmethod(alg::RosenbrockW6S4OS) = true isesdirk(alg::TRBDF2) = true function isesdirk(alg::Union{KenCarp3, KenCarp4, KenCarp5, KenCarp58, @@ -761,7 +711,6 @@ isesdirk(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::CompositeAlgorithm) = all(is_mass_matrix_alg, alg.algs) -is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true is_mass_matrix_alg(alg::NewtonAlgorithm) = !isesdirk(alg) # hack for the default alg function is_mass_matrix_alg(alg::CompositeAlgorithm{ diff --git a/src/algorithms.jl b/src/algorithms.jl index 7b7ae3ce6e..1899299f5e 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -1860,215 +1860,6 @@ function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), controller) end -################################################################################ - -# Rosenbrock Methods - -#= -#### Rosenbrock23, Rosenbrock32, ode23s, ModifiedRosenbrockIntegrator - -- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of -Scientific Computing, 18 (1), pp. 1-22. - -#### ROS2 - -- J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems - https://doi.org/10.1137/S1064827597326651 - -#### ROS3P - -- Lang, J. & Verwer, ROS3P—An Accurate Third-Order Rosenbrock Solver Designed for - Parabolic Problems J. BIT Numerical Mathematics (2001) 41: 731. doi:10.1023/A:1021900219772 - -#### ROS3, Rodas3, Ros4LStab, Rodas4, Rodas42 - -- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and - differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) - -#### ROS2PR, ROS2S, ROS3PR, Scholz4_7 --Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 - -#### RosShamp4 - -- L. F. Shampine, Implementation of Rosenbrock Methods, ACM Transactions on - Mathematical Software (TOMS), 8: 2, 93-113. doi:10.1145/355993.355994 - -#### Veldd4, Velds4 - -- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. - doi:10.1007/BF02243574 - -#### GRK4T, GRK4A - -- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control - for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 - -#### Rodas23W, Rodas3P - -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate for dense output and Julia implementation, - in progress - -#### Rodas4P - -- Steinebach G. Order-reduction of ROW-methods for DAEs and method of lines - applications. Preprint-Nr. 1741, FB Mathematik, TH Darmstadt; 1995. - -#### Rodas4P2 -- Steinebach G. (2020) Improvement of Rosenbrock-Wanner Method RODASP. - In: Reis T., Grundel S., Schoeps S. (eds) Progress in Differential-Algebraic Equations II. - Differential-Algebraic Equations Forum. Springer, Cham. https://doi.org/10.1007/978-3-030-53905-4_6 - -#### Rodas5 -- Di Marzo G. RODAS5(4) – Méthodes de Rosenbrock d’ordre 5(4) adaptées aux problemes -différentiels-algébriques. MSc mathematics thesis, Faculty of Science, -University of Geneva, Switzerland. - -#### ROS34PRw --Joachim Rang, Improved traditional Rosenbrock–Wanner methods for stiff ODEs and DAEs, - Journal of Computational and Applied Mathematics, - https://doi.org/10.1016/j.cam.2015.03.010 - -#### ROS3PRL, ROS3PRL2 --Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 - -#### ROK4a -- Tranquilli, Paul and Sandu, Adrian (2014): - Rosenbrock--Krylov Methods for Large Systems of Differential Equations - https://doi.org/10.1137/130923336 - -#### Rodas5P -- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks within the Julia Differential Equations package. - In: BIT Numerical Mathematics, 63(2), 2023 - - #### Rodas23W, Rodas3P, Rodas5Pe, Rodas5Pr -- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - - Preprint 2024 - https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf - -=# - -for Alg in [ - :ROS2, - :ROS2PR, - :ROS2S, - :ROS3, - :ROS3PR, - :Scholz4_7, - :ROS34PW1a, - :ROS34PW1b, - :ROS34PW2, - :ROS34PW3, - :ROS34PRw, - :ROS3PRL, - :ROS3PRL2, - :ROK4a, - :RosShamp4, - :Veldd4, - :Velds4, - :GRK4T, - :GRK4A, - :Ros4LStab] - @eval begin - struct $Alg{CS, AD, F, P, FDT, ST, CJ} <: - OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - end - function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = nothing, precs = DEFAULT_PRECS) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - precs) - end - end - - @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 -end - -# for Rosenbrock methods with step_limiter -for Alg in [ - :Rosenbrock23, - :Rosenbrock32, - :ROS3P, - :Rodas3, - :Rodas23W, - :Rodas3P, - :Rodas4, - :Rodas42, - :Rodas4P, - :Rodas4P2, - :Rodas5, - :Rodas5P, - :Rodas5Pe, - :Rodas5Pr] - @eval begin - struct $Alg{CS, AD, F, P, FDT, ST, CJ, StepLimiter, StageLimiter} <: - OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - step_limiter!::StepLimiter - stage_limiter!::StageLimiter - end - function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = nothing, - precs = DEFAULT_PRECS, step_limiter! = trivial_limiter!, - stage_limiter! = trivial_limiter!) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!), - typeof(stage_limiter!)}(linsolve, precs, step_limiter!, - stage_limiter!) - end - end - - @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 -end -struct GeneralRosenbrock{CS, AD, F, ST, CJ, TabType} <: - OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, Val{:forward}, ST, CJ} - tableau::TabType - factorization::F -end - -function GeneralRosenbrock(; chunk_size = Val{0}(), autodiff = true, - standardtag = Val{true}(), concrete_jac = nothing, - factorization = lu!, tableau = ROSENBROCK_DEFAULT_TABLEAU) - GeneralRosenbrock{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(factorization), - _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(tableau)}(tableau, - factorization) -end - -@doc rosenbrock_wanner_docstring( - """ - A 4th order L-stable Rosenbrock-W method (fixed step only). - """, - "RosenbrockW6S4OS", - references = """ - https://doi.org/10.1016/j.cam.2009.09.017 - """) -struct RosenbrockW6S4OS{CS, AD, F, P, FDT, ST, CJ} <: - OrdinaryDiffEqRosenbrockAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P -end -function RosenbrockW6S4OS(; chunk_size = Val{0}(), autodiff = true, - standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:central}, - linsolve = nothing, - precs = DEFAULT_PRECS) - RosenbrockW6S4OS{_unwrap_val(chunk_size), - _unwrap_val(autodiff), typeof(linsolve), typeof(precs), diff_type, - _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, - precs) -end - ###################################### for Alg in [:LawsonEuler, :NorsettEuler, :ETDRK2, :ETDRK3, :ETDRK4, :HochOst4] diff --git a/src/doc_utils.jl b/src/doc_utils.jl index e5b5681067..aa36057812 100644 --- a/src/doc_utils.jl +++ b/src/doc_utils.jl @@ -55,34 +55,34 @@ function generic_solver_docstring(description::String, end function rosenbrock_docstring(description::String, - name::String; - references::String = "", - extra_keyword_description = "", - extra_keyword_default = "", - with_step_limiter = false) - keyword_default = """ - autodiff = Val{true}(), - concrete_jac = nothing, - linsolve = nothing, - precs = DEFAULT_PRECS, - """ * extra_keyword_default - - keyword_default_description = """ - - `autodiff`: boolean to control if the Jacobian should be computed via AD or not - - `concrete_jac`: function of the form `jac!(J, u, p, t)` - - `linsolve`: custom solver for the inner linear systems - - `precs`: custom preconditioner for the inner linear solver - """ * extra_keyword_description - - if with_step_limiter - keyword_default *= "step_limiter! = OrdinaryDiffEq.trivial_limiter!,\n" - keyword_default_description *= "- `step_limiter!`: function of the form `limiter!(u, integrator, p, t)`\n" - end + name::String; + references::String = "", + extra_keyword_description = "", + extra_keyword_default = "", + with_step_limiter = false) +keyword_default = """ +autodiff = Val{true}(), +concrete_jac = nothing, +linsolve = nothing, +precs = DEFAULT_PRECS, +""" * extra_keyword_default + +keyword_default_description = """ +- `autodiff`: boolean to control if the Jacobian should be computed via AD or not +- `concrete_jac`: function of the form `jac!(J, u, p, t)` +- `linsolve`: custom solver for the inner linear systems +- `precs`: custom preconditioner for the inner linear solver +""" * extra_keyword_description + +if with_step_limiter + keyword_default *= "step_limiter! = OrdinaryDiffEq.trivial_limiter!,\n" + keyword_default_description *= "- `step_limiter!`: function of the form `limiter!(u, integrator, p, t)`\n" +end - generic_solver_docstring( - description, name, "Rosenbrock Method. ", references, - keyword_default_description, keyword_default - ) +generic_solver_docstring( + description, name, "Rosenbrock Method. ", references, + keyword_default_description, keyword_default +) end function explicit_rk_docstring(description::String, diff --git a/src/integrators/integrator_interface.jl b/src/integrators/integrator_interface.jl index 5bf13dc578..5f912ff7ee 100644 --- a/src/integrators/integrator_interface.jl +++ b/src/integrators/integrator_interface.jl @@ -87,26 +87,6 @@ end end end -@inline function DiffEqBase.get_du!(out, integrator::ODEIntegrator) - integrator.cache isa FunctionMapCache || - integrator.cache isa FunctionMapConstantCache && - error("Derivatives are not defined for this stepper.") - if integrator.cache isa FunctionMapCache - out .= integrator.cache.tmp - else - return if isdefined(integrator, :fsallast) && - !(integrator.alg isa - Union{Rosenbrock23, Rosenbrock32, Rodas23W, - Rodas3P, Rodas4, Rodas4P, Rodas4P2, Rodas5, - Rodas5P, Rodas5Pe, Rodas5Pr}) - # Special stiff interpolations do not store the right value in fsallast - out .= integrator.fsallast - else - integrator(out, integrator.t, Val{1}) - end - end -end - #TODO: Bigger caches for most algorithms @inline function DiffEqBase.get_tmp_cache(integrator::ODEIntegrator) get_tmp_cache(integrator::ODEIntegrator, integrator.alg, integrator.cache) @@ -137,11 +117,6 @@ end cache::OrdinaryDiffEqMutableCache) (cache.nlsolver.tmp, cache.nlsolver.z) end -@inline function DiffEqBase.get_tmp_cache(integrator, - alg::OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, - cache::OrdinaryDiffEqMutableCache) - (cache.tmp, cache.linsolve_tmp) -end @inline function DiffEqBase.get_tmp_cache(integrator, alg::OrdinaryDiffEqAdaptiveExponentialAlgorithm, @@ -332,15 +307,6 @@ function addat_non_user_cache!(integrator::ODEIntegrator, cache::CompositeCache, end end -function resize_non_user_cache!(integrator::ODEIntegrator, - cache::RosenbrockMutableCache, i) - cache.J = similar(cache.J, i, i) - cache.W = similar(cache.W, i, i) - resize_jac_config!(cache.jac_config, i) - resize_grad_config!(cache.grad_config, i) - nothing -end - function deleteat_non_user_cache!(integrator::ODEIntegrator, cache, idxs) # ordering doesn't matter in deterministic cache, so just resize # to match the size of u diff --git a/src/integrators/integrator_utils.jl b/src/integrators/integrator_utils.jl index a3f45f456a..f0033ca462 100644 --- a/src/integrators/integrator_utils.jl +++ b/src/integrators/integrator_utils.jl @@ -380,39 +380,6 @@ function update_uprev!(integrator) nothing end -function apply_step!(integrator) - update_uprev!(integrator) - - #Update dt if adaptive or if fixed and the dt is allowed to change - if integrator.opts.adaptive || integrator.dtchangeable - integrator.dt = integrator.dtpropose - elseif integrator.dt != integrator.dtpropose && !integrator.dtchangeable - error("The current setup does not allow for changing dt.") - end - - # Update fsal if needed - if has_discontinuity(integrator) && - first_discontinuity(integrator) == integrator.tdir * integrator.t - handle_discontinuities!(integrator) - get_current_isfsal(integrator.alg, integrator.cache) && reset_fsal!(integrator) - elseif all_fsal(integrator.alg, integrator.cache) || - get_current_isfsal(integrator.alg, integrator.cache) - if integrator.reeval_fsal || integrator.u_modified || - (integrator.alg isa DP8 && !integrator.opts.calck) || - (integrator.alg isa Union{Rosenbrock23, Rosenbrock32} && - !integrator.opts.adaptive) - reset_fsal!(integrator) - else # Do not reeval_fsal, instead copyto! over - if isinplace(integrator.sol.prob) - recursivecopy!(integrator.fsalfirst, integrator.fsallast) - else - integrator.fsalfirst = integrator.fsallast - end - end - end - return nothing -end - handle_discontinuities!(integrator) = pop_discontinuity!(integrator) function calc_dt_propose!(integrator, dtnew) diff --git a/src/interp_func.jl b/src/interp_func.jl index b1c364c734..4457b990e1 100644 --- a/src/interp_func.jl +++ b/src/interp_func.jl @@ -45,16 +45,6 @@ function DiffEqBase.interp_summary(::Type{cacheType}, Union{DP5ConstantCache, DP5Cache}} dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Rosenbrock23ConstantCache, - Rosenbrock32ConstantCache, - Rosenbrock23Cache, - Rosenbrock32Cache}} - dense ? "specialized 2nd order \"free\" stiffness-aware interpolation" : - "1st order linear" -end function DiffEqBase.interp_summary(::Type{cacheType}, dense::Bool) where { cacheType <: @@ -63,15 +53,6 @@ function DiffEqBase.interp_summary(::Type{cacheType}, dense ? "specialized 3rd order \"free\" stiffness-aware interpolation" : "1st order linear" end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Rosenbrock5ConstantCache, - Rosenbrock5Cache}} - dense ? "specialized 4rd order \"free\" stiffness-aware interpolation" : - "1st order linear" -end - function DiffEqBase.interp_summary(::Type{cacheType}, dense::Bool) where { cacheType <: Union{OwrenZen3Cache, diff --git a/test/runtests.jl b/test/runtests.jl index 1dbd745f77..7c58889134 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -201,13 +201,16 @@ end if !is_APPVEYOR && GROUP == "AlgConvergence_III" @time @safetestset "Linear Methods Tests" include("algconvergence/linear_method_tests.jl") @time @safetestset "Split Methods Tests" include("algconvergence/split_methods_tests.jl") - @time @safetestset "Rosenbrock Tests" include("algconvergence/ode_rosenbrock_tests.jl") @time @safetestset "FIRK Tests" include("algconvergence/ode_firk_tests.jl") @time @safetestset "Linear-Nonlinear Methods Tests" include("algconvergence/linear_nonlinear_convergence_tests.jl") @time @safetestset "Linear-Nonlinear Krylov Methods Tests" include("algconvergence/linear_nonlinear_krylov_tests.jl") @time @safetestset "Quadruple precision Runge-Kutta Tests" include("algconvergence/ode_quadruple_precision_tests.jl") end + if !is_APPVEYOR && GROUP == "Rosenbrock" + @time @safetestset "Rosenbrock Tests" include("../lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl") + end + if !is_APPVEYOR && GROUP == "Symplectic" @time @safetestset "Symplectic Tests" include("../lib/OrdinaryDiffEqSymplecticRK/test/symplectic_tests.jl") end From d048a8ec5f7f094c627995847039abc74aaba708 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 9 Jul 2024 18:39:34 +0530 Subject: [PATCH 002/112] format --- .../src/OrdinaryDiffEqRosenbrock.jl | 7 ++++--- lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl | 2 +- lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl | 2 +- lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl | 2 +- lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl | 2 +- lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl | 2 +- .../src/rosenbrock_interpolants.jl | 2 +- lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl index 10fdc4c5fa..d7365dfac3 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl @@ -1,7 +1,8 @@ module OrdinaryDiffEqRosenbrock -import OrdinaryDiffEq: OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, OrdinaryDiffEqRosenbrockAlgorithm, rosenbrock_docstring, - rosenbrock_wanner_docstring, +import OrdinaryDiffEq: OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, + OrdinaryDiffEqRosenbrockAlgorithm, rosenbrock_docstring, + rosenbrock_wanner_docstring, OrdinaryDiffEqMutableCache, alg_order, alg_adaptive_order, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, @@ -27,4 +28,4 @@ export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, ROS3PRL2, ROK4a, ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl b/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl index 13edd290e7..f5c68d98b1 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl @@ -49,4 +49,4 @@ isWmethod(alg::RosenbrockW6S4OS) = true alg_adaptive_order(alg::Rosenbrock23) = 3 alg_adaptive_order(alg::Rosenbrock32) = 2 -is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true \ No newline at end of file +is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true diff --git a/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl index 9cf7420395..32330c27e1 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl @@ -1807,4 +1807,4 @@ You need to change respective places in this file. `gen_initialize()` and special step expressions in macro definitions 2. `caches/rosenbrock_caches.jl` -> `gen_algcache()`, `gen_cache_struct()` 3. `tableaus/rosenbrock_tableaus.jl` -> `gen_tableau_struct()` and `gen_tableau()` -=========================================================================================# \ No newline at end of file +=========================================================================================# diff --git a/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl b/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl index d797e899b6..3f83339bd3 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl @@ -31,4 +31,4 @@ function resize_non_user_cache!(integrator::ODEIntegrator, resize_jac_config!(cache.jac_config, i) resize_grad_config!(cache.grad_config, i) nothing -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl b/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl index 3131073f94..85b496887e 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl @@ -29,4 +29,4 @@ function apply_step!(integrator) end end return nothing -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl index 6076fe7dbb..e2eb013809 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl @@ -1140,4 +1140,4 @@ end ### RosenbrockW6S4O -@RosenbrockW6S4OS(:cache) \ No newline at end of file +@RosenbrockW6S4OS(:cache) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl index e691619b70..6f50205cf1 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl @@ -364,4 +364,4 @@ end @views @.. broadcast=false out=(-6 * k[2][idxs] + 6 * k[3][idxs] - 24 * Θ * k[3][idxs]) / dt^3 out -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl index 66dc620871..493c67111a 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl @@ -830,4 +830,4 @@ beta3 = 6.8619167645278386e-2 beta4 = 0.8289547562599182 beta5 = 7.9630136489868164e-2 alpha64 = -0.2076823627400282 -=# \ No newline at end of file +=# From 312ee160980886585660230deee33d4279ca513c Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 9 Jul 2024 18:46:31 +0530 Subject: [PATCH 003/112] Rodas3P --- lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl index d7365dfac3..15728e5c63 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl @@ -10,9 +10,9 @@ import OrdinaryDiffEq: OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, using DiffEqBase, MuladdMacro include("algorithms.jl") +include("generic_rosenbrock.jl") include("alg_utils.jl") include("rosenbrock_tableaus.jl") -include("generic_rosenbrock.jl") include("rosenbrock_caches.jl") include("integrator_interface.jl") include("integrator_utils.jl") @@ -28,4 +28,4 @@ export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, ROS3PRL2, ROK4a, ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 -end +end \ No newline at end of file From dd11ccffce6ba44147d7abfe1075d48d8ddd2bec Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 9 Jul 2024 18:51:12 +0530 Subject: [PATCH 004/112] Rodas3P --- lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl index 15728e5c63..73c272d63e 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl @@ -9,8 +9,8 @@ import OrdinaryDiffEq: OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, OrdinaryDiffEqAdaptiveAlgorithm using DiffEqBase, MuladdMacro -include("algorithms.jl") include("generic_rosenbrock.jl") +include("algorithms.jl") include("alg_utils.jl") include("rosenbrock_tableaus.jl") include("rosenbrock_caches.jl") From 867559366b72cc63f8ee8ea67196897be291cc63 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 9 Jul 2024 18:56:18 +0530 Subject: [PATCH 005/112] Rodas3P --- lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl | 16 ++++++++++++++++ src/alg_utils.jl | 16 +--------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl b/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl index f5c68d98b1..7bd9bcce2d 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl @@ -34,6 +34,17 @@ alg_order(alg::Rodas5P) = 5 alg_order(alg::Rodas5Pr) = 5 alg_order(alg::Rodas5Pe) = 5 +isfsal(alg::Rodas3P) = false +isfsal(alg::Rodas23W) = false +isfsal(alg::Rodas5) = false +isfsal(alg::Rodas5P) = false +isfsal(alg::Rodas5Pr) = false +isfsal(alg::Rodas5Pe) = false +isfsal(alg::Rodas4) = false +isfsal(alg::Rodas42) = false +isfsal(alg::Rodas4P) = false +isfsal(alg::Rodas4P2) = false + isWmethod(alg::Rosenbrock23) = true isWmethod(alg::Rosenbrock32) = true isWmethod(alg::Rodas23W) = true @@ -50,3 +61,8 @@ alg_adaptive_order(alg::Rosenbrock23) = 3 alg_adaptive_order(alg::Rosenbrock32) = 2 is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true + +function is_mass_matrix_alg(alg::CompositeAlgorithm{ + <:Any, <:Tuple{Tsit5, Rosenbrock23, Rodas5P, FBDF, FBDF}}) + true +end \ No newline at end of file diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 2fbde7a9e5..52498dd3d0 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -30,16 +30,6 @@ isfsal(tab::DiffEqBase.ExplicitRKTableau) = tab.fsal # isfsal(alg::CompositeAlgorithm) = isfsal(alg.algs[alg.current]) isfsal(alg::FunctionMap) = false -isfsal(alg::Rodas3P) = false -isfsal(alg::Rodas23W) = false -isfsal(alg::Rodas5) = false -isfsal(alg::Rodas5P) = false -isfsal(alg::Rodas5Pr) = false -isfsal(alg::Rodas5Pe) = false -isfsal(alg::Rodas4) = false -isfsal(alg::Rodas42) = false -isfsal(alg::Rodas4P) = false -isfsal(alg::Rodas4P2) = false # Pseudo Non-FSAL isfsal(alg::PDIRK44) = false isfsal(alg::DImplicitEuler) = false @@ -712,8 +702,4 @@ isesdirk(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::CompositeAlgorithm) = all(is_mass_matrix_alg, alg.algs) is_mass_matrix_alg(alg::NewtonAlgorithm) = !isesdirk(alg) -# hack for the default alg -function is_mass_matrix_alg(alg::CompositeAlgorithm{ - <:Any, <:Tuple{Tsit5, Rosenbrock23, Rodas5P, FBDF, FBDF}}) - true -end +# hack for the default alg \ No newline at end of file From 29066373cb6257ef3c81a649f9b79f408df5829c Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 9 Jul 2024 19:03:55 +0530 Subject: [PATCH 006/112] Rodas Cache --- lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl | 9 +++++++++ src/interp_func.jl | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl b/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl index fe7a5e935f..4273153492 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl @@ -17,3 +17,12 @@ function DiffEqBase.interp_summary(::Type{cacheType}, dense ? "specialized 4rd order \"free\" stiffness-aware interpolation" : "1st order linear" end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache, + Rodas4Cache, Rodas23WCache, Rodas3PCache}} + dense ? "specialized 3rd order \"free\" stiffness-aware interpolation" : + "1st order linear" +end \ No newline at end of file diff --git a/src/interp_func.jl b/src/interp_func.jl index 4457b990e1..4e31fe0efa 100644 --- a/src/interp_func.jl +++ b/src/interp_func.jl @@ -45,14 +45,6 @@ function DiffEqBase.interp_summary(::Type{cacheType}, Union{DP5ConstantCache, DP5Cache}} dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache, - Rodas4Cache, Rodas23WCache, Rodas3PCache}} - dense ? "specialized 3rd order \"free\" stiffness-aware interpolation" : - "1st order linear" -end function DiffEqBase.interp_summary(::Type{cacheType}, dense::Bool) where { cacheType <: Union{OwrenZen3Cache, From 49d65ec16da064f5b63c7228b2672c14ce1019dd Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Wed, 10 Jul 2024 08:53:53 +0530 Subject: [PATCH 007/112] Rosenbrock23 --- lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl index ae485281ef..393075943c 100644 --- a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl +++ b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl @@ -1,8 +1,9 @@ module OrdinaryDiffEqDefault -using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, Rosenbrock23, Rodas5P, FBDF, +using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, Rodas5P, FBDF, alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch +using OrdinaryDiffEqRosenbrock import OrdinaryDiffEq: is_mass_matrix_alg, default_autoswitch import LinearSolve using LinearAlgebra: I, isdiag From a0bc75e2762006bd28b110f0b9582b2eae4c86c0 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Wed, 10 Jul 2024 08:56:42 +0530 Subject: [PATCH 008/112] Rodas5P --- lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl index 393075943c..6f8841835c 100644 --- a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl +++ b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl @@ -1,9 +1,9 @@ module OrdinaryDiffEqDefault -using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, Rodas5P, FBDF, +using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, FBDF, alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch -using OrdinaryDiffEqRosenbrock +using OrdinaryDiffEqRosenbrock: Rosenbrock23, Rodas5P import OrdinaryDiffEq: is_mass_matrix_alg, default_autoswitch import LinearSolve using LinearAlgebra: I, isdiag From 6f6472bf3f118343ce8b85d48a3e8eecd787afa8 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Wed, 10 Jul 2024 09:01:38 +0530 Subject: [PATCH 009/112] Rosenbrock23 --- lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl index 6f8841835c..3c055b9ec2 100644 --- a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl +++ b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl @@ -3,7 +3,7 @@ module OrdinaryDiffEqDefault using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, FBDF, alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch -using OrdinaryDiffEqRosenbrock: Rosenbrock23, Rodas5P +using OrdinaryDiffEq: Rodas5P, Rosenbrock23 import OrdinaryDiffEq: is_mass_matrix_alg, default_autoswitch import LinearSolve using LinearAlgebra: I, isdiag From 6027a82d3bcd3c610167cde4ea3696f2a0a55e17 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 11 Jul 2024 07:36:26 +0530 Subject: [PATCH 010/112] Changes --- .../src/OrdinaryDiffEqDefault.jl | 2 +- test/runtests.jl | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl index 3c055b9ec2..66bc63a4bd 100644 --- a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl +++ b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl @@ -3,7 +3,7 @@ module OrdinaryDiffEqDefault using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, FBDF, alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch -using OrdinaryDiffEq: Rodas5P, Rosenbrock23 +using OrdinaryDiffEqRosenbrock: Rodas5P, Rosenbrock23 import OrdinaryDiffEq: is_mass_matrix_alg, default_autoswitch import LinearSolve using LinearAlgebra: I, isdiag diff --git a/test/runtests.jl b/test/runtests.jl index 7c58889134..081f686c17 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -71,6 +71,18 @@ function activate_symplectic_rk() Pkg.instantiate() end +function activate_default() + Pkg.activate("../lib/OrdinaryDiffEqDefault") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + +function activate_rosenbrock() + Pkg.activate("../lib/OrdinaryDiffEqRosenbrock") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + #Start Test Script @time begin From 7bfa297f62506e8cd50e3aeb3c23a671e23a543e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 14:42:44 +0530 Subject: [PATCH 011/112] More solvers added --- lib/OrdinaryDiffEqBDF/Project.toml | 4 + .../src/OrdinaryDiffEqBDF.jl | 5 + lib/OrdinaryDiffEqBDF/src/alg_utils.jl | 23 + lib/OrdinaryDiffEqBDF/src/algorithms.jl | 223 ++ .../OrdinaryDiffEqBDF/src}/bdf_caches.jl | 0 .../src}/bdf_perform_step.jl | 2 +- .../src/OrdinaryDiffEqDefault.jl | 5 +- lib/OrdinaryDiffEqExplicitRK/Project.toml | 4 + .../src/OrdinaryDiffEqExplicitRK.jl | 5 + lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl | 7 + .../src/algorithms.jl | 6 + .../src/explicit_rk_caches.jl | 60 + .../src/explicit_rk_perform_step.jl | 240 ++ lib/OrdinaryDiffEqFIRK/Project.toml | 4 + .../src/OrdinaryDiffEqFIRK.jl | 5 + lib/OrdinaryDiffEqFIRK/src/alg_utils.jl | 7 + lib/OrdinaryDiffEqFIRK/src/algorithms.jl | 106 + lib/OrdinaryDiffEqFIRK/src/controllers.jl | 25 + .../OrdinaryDiffEqFIRK/src}/firk_caches.jl | 0 .../src}/firk_perform_step.jl | 2 +- .../OrdinaryDiffEqFIRK/src}/firk_tableaus.jl | 2 +- .../src/integrator_interface.jl | 4 + .../test}/ode_firk_tests.jl | 2 +- lib/OrdinaryDiffEqFIRK/test/runtests.jl | 0 lib/OrdinaryDiffEqSDIRK/Project.toml | 4 + .../src/OrdinaryDiffEqSDIRK.jl | 5 + lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl | 47 + lib/OrdinaryDiffEqSDIRK/src/algorithms.jl | 864 +++++++ .../src}/kencarp_kvaerno_caches.jl | 2 +- .../src}/kencarp_kvaerno_perform_step.jl | 2 +- .../OrdinaryDiffEqSDIRK/src}/sdirk_caches.jl | 2 +- .../src}/sdirk_perform_step.jl | 2 +- .../src}/sdirk_tableaus.jl | 2 +- lib/OrdinaryHighOrderRK/Project.toml | 4 + .../src/OrdinaryHighOrderRK.jl | 5 + lib/OrdinaryHighOrderRK/src/alg_utils.jl | 11 + lib/OrdinaryHighOrderRK/src/algorithms.jl | 61 + .../src}/high_order_rk_addsteps.jl | 2 +- .../src}/high_order_rk_caches.jl | 2 +- .../src}/high_order_rk_perform_step.jl | 2 +- .../src}/high_order_rk_tableaus.jl | 2 +- lib/OrdinaryHighOrderRK/src/interp_func.jl | 6 + lib/OrdinaryHighOrderRK/src/interpolants.jl | 138 ++ lib/OrdinaryLowOrderRK/Project.toml | 4 + .../src/OrdinaryLowOrderRK.jl | 5 + lib/OrdinaryLowOrderRK/src/alg_utils.jl | 47 + lib/OrdinaryLowOrderRK/src/algorithms.jl | 632 +++++ .../src/fixed_timestep_perform_step.jl | 487 ++++ lib/OrdinaryLowOrderRK/src/interp_func.jl | 52 + .../OrdinaryLowOrderRK/src}/interpolants.jl | 2141 ++++++++--------- .../src}/low_order_rk_addsteps.jl | 0 .../src}/low_order_rk_caches.jl | 24 + .../src}/low_order_rk_perform_step.jl | 2 +- .../src}/low_order_rk_tableaus.jl | 2 +- .../src}/split_perform_step.jl | 2 +- .../test}/owrenzen_tests.jl | 2 +- lib/OrdinaryLowOrderRK/test/runtests.jl | 0 src/OrdinaryDiffEq.jl | 78 +- src/alg_utils.jl | 133 +- src/algorithms.jl | 1616 +------------ src/algorithms/explicit_rk.jl | 463 ---- src/caches/basic_caches.jl | 87 +- src/integrators/controllers.jl | 26 - src/integrators/integrator_interface.jl | 4 - src/interp_func.jl | 52 - src/perform_step/explicit_rk_perform_step.jl | 240 -- .../fixed_timestep_perform_step.jl | 490 +--- test/runtests.jl | 44 +- 68 files changed, 4285 insertions(+), 4252 deletions(-) create mode 100644 lib/OrdinaryDiffEqBDF/Project.toml create mode 100644 lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl create mode 100644 lib/OrdinaryDiffEqBDF/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqBDF/src/algorithms.jl rename {src/caches => lib/OrdinaryDiffEqBDF/src}/bdf_caches.jl (100%) rename {src/perform_step => lib/OrdinaryDiffEqBDF/src}/bdf_perform_step.jl (99%) create mode 100644 lib/OrdinaryDiffEqExplicitRK/Project.toml create mode 100644 lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl create mode 100644 lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl create mode 100644 lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl create mode 100644 lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl create mode 100644 lib/OrdinaryDiffEqFIRK/Project.toml create mode 100644 lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl create mode 100644 lib/OrdinaryDiffEqFIRK/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqFIRK/src/algorithms.jl create mode 100644 lib/OrdinaryDiffEqFIRK/src/controllers.jl rename {src/caches => lib/OrdinaryDiffEqFIRK/src}/firk_caches.jl (100%) rename {src/perform_step => lib/OrdinaryDiffEqFIRK/src}/firk_perform_step.jl (99%) rename {src/tableaus => lib/OrdinaryDiffEqFIRK/src}/firk_tableaus.jl (99%) create mode 100644 lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl rename {test/algconvergence => lib/OrdinaryDiffEqFIRK/test}/ode_firk_tests.jl (99%) create mode 100644 lib/OrdinaryDiffEqFIRK/test/runtests.jl create mode 100644 lib/OrdinaryDiffEqSDIRK/Project.toml create mode 100644 lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl create mode 100644 lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqSDIRK/src/algorithms.jl rename {src/caches => lib/OrdinaryDiffEqSDIRK/src}/kencarp_kvaerno_caches.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqSDIRK/src}/kencarp_kvaerno_perform_step.jl (99%) rename {src/caches => lib/OrdinaryDiffEqSDIRK/src}/sdirk_caches.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqSDIRK/src}/sdirk_perform_step.jl (99%) rename {src/tableaus => lib/OrdinaryDiffEqSDIRK/src}/sdirk_tableaus.jl (99%) create mode 100644 lib/OrdinaryHighOrderRK/Project.toml create mode 100644 lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl create mode 100644 lib/OrdinaryHighOrderRK/src/alg_utils.jl create mode 100644 lib/OrdinaryHighOrderRK/src/algorithms.jl rename {src/dense => lib/OrdinaryHighOrderRK/src}/high_order_rk_addsteps.jl (99%) rename {src/caches => lib/OrdinaryHighOrderRK/src}/high_order_rk_caches.jl (99%) rename {src/perform_step => lib/OrdinaryHighOrderRK/src}/high_order_rk_perform_step.jl (99%) rename {src/tableaus => lib/OrdinaryHighOrderRK/src}/high_order_rk_tableaus.jl (99%) create mode 100644 lib/OrdinaryHighOrderRK/src/interp_func.jl create mode 100644 lib/OrdinaryHighOrderRK/src/interpolants.jl create mode 100644 lib/OrdinaryLowOrderRK/Project.toml create mode 100644 lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl create mode 100644 lib/OrdinaryLowOrderRK/src/alg_utils.jl create mode 100644 lib/OrdinaryLowOrderRK/src/algorithms.jl create mode 100644 lib/OrdinaryLowOrderRK/src/fixed_timestep_perform_step.jl create mode 100644 lib/OrdinaryLowOrderRK/src/interp_func.jl rename {src/dense => lib/OrdinaryLowOrderRK/src}/interpolants.jl (88%) rename {src/dense => lib/OrdinaryLowOrderRK/src}/low_order_rk_addsteps.jl (100%) rename {src/caches => lib/OrdinaryLowOrderRK/src}/low_order_rk_caches.jl (98%) rename {src/perform_step => lib/OrdinaryLowOrderRK/src}/low_order_rk_perform_step.jl (99%) rename {src/tableaus => lib/OrdinaryLowOrderRK/src}/low_order_rk_tableaus.jl (99%) rename {src/perform_step => lib/OrdinaryLowOrderRK/src}/split_perform_step.jl (99%) rename {test/algconvergence => lib/OrdinaryLowOrderRK/test}/owrenzen_tests.jl (97%) create mode 100644 lib/OrdinaryLowOrderRK/test/runtests.jl diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml new file mode 100644 index 0000000000..526d7700ce --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -0,0 +1,4 @@ +name = "OrdinaryDiffEqBDF" +uuid = "34d55129-80d4-4dd1-bb14-71372a5ab94f" +authors = ["ParamThakkar123 "] +version = "1.0.0" diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl new file mode 100644 index 0000000000..627af4524d --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -0,0 +1,5 @@ +module OrdinaryDiffEqBDF + +greet() = print("Hello World!") + +end # module OrdinaryDiffEqBDF diff --git a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl new file mode 100644 index 0000000000..1a7a3cc73c --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl @@ -0,0 +1,23 @@ +alg_extrapolates(alg::ABDF2) = true +alg_extrapolates(alg::SBDF) = true +alg_extrapolates(alg::MEBDF2) = true + +alg_order(alg::ABDF2) = 2 +alg_order(alg::SBDF) = alg.order +alg_order(alg::QNDF1) = 1 +alg_order(alg::MEBDF2) = 2 +alg_order(alg::FBDF) = 1 #dummy value +alg_order(alg::QNDF2) = 2 +alg_order(alg::QNDF) = 1 #dummy value + +get_current_alg_order(alg::QNDF, cache) = cache.order +get_current_alg_order(alg::FBDF, cache) = cache.order + +get_current_adaptive_order(alg::FBDF, cache) = cache.order + +qsteady_max_default(alg::QNDF) = 2 // 1 +qsteady_max_default(alg::QNDF2) = 2 // 1 +qsteady_max_default(alg::QNDF1) = 2 // 1 + +qsteady_min_default(alg::FBDF) = 9 // 10 +qsteady_max_default(alg::FBDF) = 2 // 1 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl new file mode 100644 index 0000000000..0481ca06e0 --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -0,0 +1,223 @@ +""" +Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. Implicit-Explicit Methods for Time- +Dependent Partial Differential Equations. 1995 Society for Industrial and Applied Mathematics +Journal on Numerical Analysis, 32(3), pp 797-823, 1995. doi: https://doi.org/10.1137/0732037 +""" +struct SBDF{CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + order::Int + ark::Bool +end + +function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, ark = false) + SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(linsolve, + nlsolve, + precs, + κ, + tol, + extrapolant, + order, + ark) +end + +# All keyword form needed for remake +function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, + order, ark = false) + SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(linsolve, + nlsolve, + precs, + κ, + tol, + extrapolant, + order, + ark) +end + +""" +E. Alberdi Celayaa, J. J. Anza Aguirrezabalab, P. Chatzipantelidisc. Implementation of +an Adaptive BDF2 Formula and Comparison with The MATLAB Ode15s. Procedia Computer Science, +29, pp 1014-1026, 2014. doi: https://doi.org/10.1016/j.procs.2014.05.091 + +ABDF2: Multistep Method +An adaptive order 2 L-stable fixed leading coefficient multistep BDF method. +""" +struct ABDF2{CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function ABDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + κ = nothing, tol = nothing, linsolve = nothing, precs = DEFAULT_PRECS, + nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :Standard, step_limiter! = trivial_limiter!) + ABDF2{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(step_limiter!)}(linsolve, nlsolve, precs, κ, tol, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +QNDF1: Multistep Method +An adaptive order 1 quasi-constant timestep L-stable numerical differentiation function (NDF) method. +Optional parameter kappa defaults to Shampine's accuracy-optimal -0.1850. + +See also `QNDF`. +""" +struct QNDF1{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, kappa = -0.1850, + controller = :Standard, step_limiter! = trivial_limiter!) + QNDF1{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(kappa), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + kappa, + controller, + step_limiter!) +end + +""" +QNDF2: Multistep Method +An adaptive order 2 quasi-constant timestep L-stable numerical differentiation function (NDF) method. + +See also `QNDF`. +""" +struct QNDF2{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, kappa = -1 // 9, + controller = :Standard, step_limiter! = trivial_limiter!) + QNDF2{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(kappa), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + kappa, + controller, + step_limiter!) +end + +""" +QNDF: Multistep Method +An adaptive order quasi-constant timestep NDF method. +Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). + +@article{shampine1997matlab, +title={The matlab ode suite}, +author={Shampine, Lawrence F and Reichelt, Mark W}, +journal={SIAM journal on scientific computing}, +volume={18}, +number={1}, +pages={1--22}, +year={1997}, +publisher={SIAM} +} +""" +struct QNDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, kappa = promote(-0.1850, -1 // 9, -0.0823, -0.0415, 0), + controller = :Standard, step_limiter! = trivial_limiter!) where {MO} + QNDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(kappa), typeof(step_limiter!)}( + max_order, linsolve, nlsolve, precs, κ, tol, + extrapolant, kappa, controller, step_limiter!) +end + +""" +MEBDF2: Multistep Method +The second order Modified Extended BDF method, which has improved stability properties over the standard BDF. +Fixed timestep only. +""" +struct MEBDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function MEBDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant) + MEBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end \ No newline at end of file diff --git a/src/caches/bdf_caches.jl b/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl similarity index 100% rename from src/caches/bdf_caches.jl rename to lib/OrdinaryDiffEqBDF/src/bdf_caches.jl diff --git a/src/perform_step/bdf_perform_step.jl b/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl similarity index 99% rename from src/perform_step/bdf_perform_step.jl rename to lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl index e52686c8cc..082d4faa03 100644 --- a/src/perform_step/bdf_perform_step.jl +++ b/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl @@ -1342,4 +1342,4 @@ function perform_step!(integrator, cache::FBDFCache{max_order}, f(integrator.fsallast, u, p, tdt) integrator.stats.nf += 1 -end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl index 66bc63a4bd..ea680d5d73 100644 --- a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl +++ b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl @@ -1,9 +1,8 @@ module OrdinaryDiffEqDefault using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, FBDF, - alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, - CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch -using OrdinaryDiffEqRosenbrock: Rodas5P, Rosenbrock23 + alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, + CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch import OrdinaryDiffEq: is_mass_matrix_alg, default_autoswitch import LinearSolve using LinearAlgebra: I, isdiag diff --git a/lib/OrdinaryDiffEqExplicitRK/Project.toml b/lib/OrdinaryDiffEqExplicitRK/Project.toml new file mode 100644 index 0000000000..899f18dcc8 --- /dev/null +++ b/lib/OrdinaryDiffEqExplicitRK/Project.toml @@ -0,0 +1,4 @@ +name = "OrdinaryDiffEqExplicitRK" +uuid = "a6f9a3f1-1c5b-4457-b8d8-bad5275751bf" +authors = ["ParamThakkar123 "] +version = "0.1.0" diff --git a/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl b/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl new file mode 100644 index 0000000000..9b460a52bd --- /dev/null +++ b/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl @@ -0,0 +1,5 @@ +module OrdinaryDiffEqExplicitRK + +greet() = print("Hello World!") + +end # module OrdinaryDiffEqExplicitRK diff --git a/lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl b/lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl new file mode 100644 index 0000000000..7e0b5ed0ea --- /dev/null +++ b/lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl @@ -0,0 +1,7 @@ +isfsal(tab::DiffEqBase.ExplicitRKTableau) = tab.fsal + +alg_order(alg::ExplicitRK) = alg.tableau.order + +alg_adaptive_order(alg::ExplicitRK) = alg.tableau.adaptiveorder + +alg_stability_size(alg::ExplicitRK) = alg.tableau.stability_size \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl b/lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl new file mode 100644 index 0000000000..39f6b6ba79 --- /dev/null +++ b/lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl @@ -0,0 +1,6 @@ +struct ExplicitRK{TabType} <: OrdinaryDiffEqAdaptiveAlgorithm + tableau::TabType +end +ExplicitRK(; tableau = ODE_DEFAULT_TABLEAU) = ExplicitRK(tableau) + +TruncatedStacktraces.@truncate_stacktrace ExplicitRK \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl b/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl new file mode 100644 index 0000000000..f2234f843c --- /dev/null +++ b/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl @@ -0,0 +1,60 @@ +@cache struct ExplicitRKCache{uType, rateType, uNoUnitsType, TabType} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + utilde::rateType + atmp::uNoUnitsType + fsalfirst::rateType + fsallast::rateType + kk::Vector{rateType} + tab::TabType +end + +TruncatedStacktraces.@truncate_stacktrace ExplicitRKCache 1 + +function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + kk = Vector{typeof(rate_prototype)}(undef, 0) + for i in 1:(alg.tableau.stages) + push!(kk, zero(rate_prototype)) + end + fsalfirst = kk[1] + if isfsal(alg.tableau) + fsallast = kk[end] + else + fsallast = zero(rate_prototype) + end + utilde = zero(rate_prototype) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tab = ExplicitRKConstantCache(alg.tableau, rate_prototype) + ExplicitRKCache(u, uprev, tmp, utilde, atmp, fsalfirst, fsallast, kk, tab) +end + +struct ExplicitRKConstantCache{MType, VType, KType} <: OrdinaryDiffEqConstantCache + A::MType + c::VType + α::VType + αEEst::VType + stages::Int + kk::KType +end + +function ExplicitRKConstantCache(tableau, rate_prototype) + @unpack A, c, α, αEEst, stages = tableau + A = copy(A') # Transpose A to column major looping + kk = Array{typeof(rate_prototype)}(undef, stages) # Not ks since that's for integrator.opts.dense + αEEst = isempty(αEEst) ? αEEst : α .- αEEst + ExplicitRKConstantCache(A, c, α, αEEst, stages, kk) +end + +function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + ExplicitRKConstantCache(alg.tableau, rate_prototype) +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl b/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl new file mode 100644 index 0000000000..94ea9e4856 --- /dev/null +++ b/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl @@ -0,0 +1,240 @@ +function initialize!(integrator, cache::ExplicitRKConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::ExplicitRKConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + alg = unwrap_alg(integrator, false) + @unpack A, c, α, αEEst, stages = cache + @unpack kk = cache + + # Calc First + kk[1] = integrator.fsalfirst + + # Calc Middle + for i in 2:(stages - 1) + utilde = zero(kk[1]) + for j in 1:(i - 1) + utilde = utilde + A[j, i] * kk[j] + end + kk[i] = f(uprev + dt * utilde, p, t + c[i] * dt) + integrator.stats.nf += 1 + end + + #Calc Last + utilde_last = zero(kk[1]) + for j in 1:(stages - 1) + utilde_last = utilde_last + A[j, end] * kk[j] + end + u_beforefinal = uprev + dt * utilde_last + kk[end] = f(u_beforefinal, p, t + c[end] * dt) + integrator.stats.nf += 1 + integrator.fsallast = kk[end] # Uses fsallast as temp even if not fsal + + # Accumulate Result + accum = α[1] * kk[1] + for i in 2:stages + accum = accum + α[i] * kk[i] + end + u = uprev + dt * accum + + if integrator.alg isa CompositeAlgorithm + # Hairer II, page 22 modified to use Inf norm + n = maximum(abs.((kk[end] .- kk[end - 1]) / (u .- u_beforefinal))) + integrator.eigen_est = integrator.opts.internalnorm(n, t) + end + + if integrator.opts.adaptive + utilde = αEEst[1] .* kk[1] + for i in 2:stages + utilde = utilde + αEEst[i] * kk[i] + end + atmp = calculate_residuals(dt * utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if !isfsal(alg.tableau) + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + end + + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::ExplicitRKCache) + integrator.kshortsize = 2 + integrator.fsallast = cache.fsallast + integrator.fsalfirst = cache.kk[1] + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@generated function accumulate_explicit_stages!(out, A, uprev, kk, dt, ::Val{s}, + ::Val{r} = Val(s)) where {s, r} + if s == 1 + return :(@muladd @.. broadcast=false out=uprev + dt * kk[1]) + elseif s == 2 + # Note that `A` is transposed + return :(@muladd @.. broadcast=false out=uprev + dt * (A[1, $r] * kk[1])) + else + expr = :(@muladd @.. broadcast=false out=uprev + + dt * (A[1, $r] * kk[1] + A[2, $r] * kk[2])) + acc = expr.args[end].args[end].args[end].args[end].args[end].args + for i in 3:(s - 1) + push!(acc, :(A[$i, $r] * kk[$i])) + end + return expr + end +end + +@generated function accumulate_EEst!(out, αEEst, kk, dt, ::Val{s}) where {s} + if s == 1 + return :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1])) + else + expr = :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1] + αEEst[2] * kk[2])) + acc = expr.args[end].args[end].args[end].args[end].args + for i in 3:s + push!(acc, :(αEEst[$i] * kk[$i])) + end + return expr + end +end + +function accumulate_EEst!(out, αEEst, utilde, kk, dt, stages) + @.. broadcast=false utilde=αEEst[1] * kk[1] + for i in 2:stages + @.. broadcast=false utilde=utilde + αEEst[i] * kk[i] + end + @.. broadcast=false out=dt * utilde +end + +@muladd function compute_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, + stages::Integer) where {F} + # Middle + for i in 2:(stages - 1) + @.. broadcast=false utilde=zero(kk[1][1]) + for j in 1:(i - 1) + @.. broadcast=false utilde=utilde + A[j, i] * kk[j] + end + @.. broadcast=false tmp=uprev + dt * utilde + f(kk[i], tmp, p, t + c[i] * dt) + end + + #Last + @.. broadcast=false utilde=zero(kk[1][1]) + for j in 1:(stages - 1) + @.. broadcast=false utilde=utilde + A[j, end] * kk[j] + end + @.. broadcast=false u=uprev + dt * utilde + f(kk[end], u, p, t + c[end] * dt) #fsallast is tmp even if not fsal + return nothing +end + +@generated function compute_stages!(f::F, A, c, u, tmp, uprev, kk, p, t, dt, + ::Val{s}) where {F, s} + quote + Base.@nexprs $(s - 2) i′->begin + i = i′ + 1 + accumulate_explicit_stages!(tmp, A, uprev, kk, dt, Val(i)) + f(kk[i], tmp, p, t + c[i] * dt) + end + accumulate_explicit_stages!(u, A, uprev, kk, dt, Val(s)) + f(kk[s], u, p, t + c[end] * dt) + end +end + +function runtime_split_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, + stages::Integer) where {F} + Base.@nif 17 (s->(s == stages)) (s->compute_stages!(f, A, c, u, tmp, uprev, kk, p, t, + dt, Val(s))) (s->compute_stages!(f, + A, + c, + utilde, + u, + tmp, + uprev, + kk, + p, + t, + dt, + stages)) +end + +function accumulate_fsal!(u, α, utilde, uprev, kk, dt, stages) + @.. broadcast=false utilde=α[1] * kk[1] + for i in 2:stages + @.. broadcast=false utilde=utilde + α[i] * kk[i] + end + @.. broadcast=false u=uprev + dt * utilde +end + +function runtime_split_fsal!(out, A, utilde, uprev, kk, dt, stages) + Base.@nif 17 (s->(s == stages)) (s->accumulate_explicit_stages!(out, A, uprev, kk, dt, + Val(s + 1), Val(1))) (s->accumulate_fsal!(out, + A, + utilde, + uprev, + kk, + dt, + stages)) +end + +function runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) + Base.@nif 17 (s->(s == stages)) (s->accumulate_EEst!(tmp, αEEst, kk, dt, Val(s))) (s->accumulate_EEst!( + tmp, + αEEst, + utilde, + kk, + dt, + stages)) +end + +@muladd function perform_step!(integrator, cache::ExplicitRKCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + alg = unwrap_alg(integrator, false) + # αEEst is `α - αEEst` + @unpack A, c, α, αEEst, stages = cache.tab + @unpack kk, utilde, tmp, atmp = cache + + runtime_split_stages!(f, A, c, utilde, u, tmp, uprev, kk, p, t, dt, stages) + integrator.stats.nf += stages - 1 + + #Accumulate + if !isfsal(alg.tableau) + runtime_split_fsal!(u, α, utilde, uprev, kk, dt, stages) + end + + if integrator.alg isa CompositeAlgorithm + # Hairer II, page 22 modified to use Inf norm + @.. broadcast=false utilde=abs((kk[end] - kk[end - 1]) / (u - tmp)) + integrator.eigen_est = integrator.opts.internalnorm(norm(utilde, Inf), t) + end + + if integrator.opts.adaptive + runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) + calculate_residuals!(atmp, tmp, uprev, u, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if !isfsal(alg.tableau) + f(integrator.fsallast, u, p, t + dt) + integrator.stats.nf += 1 + end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/Project.toml b/lib/OrdinaryDiffEqFIRK/Project.toml new file mode 100644 index 0000000000..0b8a6bc963 --- /dev/null +++ b/lib/OrdinaryDiffEqFIRK/Project.toml @@ -0,0 +1,4 @@ +name = "OrdinaryDiffEqFIRK" +uuid = "1072fcc4-aad5-4cac-8081-8f348bae166b" +authors = ["ParamThakkar123 "] +version = "0.1.0" diff --git a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl new file mode 100644 index 0000000000..150ae7c5f0 --- /dev/null +++ b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl @@ -0,0 +1,5 @@ +module OrdinaryDiffEqFIRK + +greet() = print("Hello World!") + +end diff --git a/lib/OrdinaryDiffEqFIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqFIRK/src/alg_utils.jl new file mode 100644 index 0000000000..d809df6101 --- /dev/null +++ b/lib/OrdinaryDiffEqFIRK/src/alg_utils.jl @@ -0,0 +1,7 @@ +qmax_default(alg::Union{RadauIIA3, RadauIIA5}) = 8 + +alg_order(alg::RadauIIA3) = 3 +alg_order(alg::RadauIIA5) = 5 + +alg_adaptive_order(alg::RadauIIA3) = 1 +alg_adaptive_order(alg::RadauIIA5) = 3 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/algorithms.jl b/lib/OrdinaryDiffEqFIRK/src/algorithms.jl new file mode 100644 index 0000000000..c57945d9b0 --- /dev/null +++ b/lib/OrdinaryDiffEqFIRK/src/algorithms.jl @@ -0,0 +1,106 @@ +# FIRK Methods + +""" +@article{hairer1999stiff, +title={Stiff differential equations solved by Radau methods}, +author={Hairer, Ernst and Wanner, Gerhard}, +journal={Journal of Computational and Applied Mathematics}, +volume={111}, +number={1-2}, +pages={93--111}, +year={1999}, +publisher={Elsevier} +} + +RadauIIA3: Fully-Implicit Runge-Kutta Method +An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. +""" +struct RadauIIA3{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + extrapolant::Symbol + κ::Tol + maxiters::Int + fast_convergence_cutoff::C1 + new_W_γdt_cutoff::C2 + controller::Symbol + step_limiter!::StepLimiter +end + +function RadauIIA3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, + extrapolant = :dense, fast_convergence_cutoff = 1 // 5, + new_W_γdt_cutoff = 1 // 5, + controller = :Predictive, κ = nothing, maxiters = 10, + step_limiter! = trivial_limiter!) + RadauIIA3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(fast_convergence_cutoff), + typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, + precs, + extrapolant, + κ, + maxiters, + fast_convergence_cutoff, + new_W_γdt_cutoff, + controller, + step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace RadauIIA3 + +""" +@article{hairer1999stiff, +title={Stiff differential equations solved by Radau methods}, +author={Hairer, Ernst and Wanner, Gerhard}, +journal={Journal of Computational and Applied Mathematics}, +volume={111}, +number={1-2}, +pages={93--111}, +year={1999}, +publisher={Elsevier} +} + +RadauIIA5: Fully-Implicit Runge-Kutta Method +An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. +""" +struct RadauIIA5{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + smooth_est::Bool + extrapolant::Symbol + κ::Tol + maxiters::Int + fast_convergence_cutoff::C1 + new_W_γdt_cutoff::C2 + controller::Symbol + step_limiter!::StepLimiter +end + +function RadauIIA5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, + extrapolant = :dense, fast_convergence_cutoff = 1 // 5, + new_W_γdt_cutoff = 1 // 5, + controller = :Predictive, κ = nothing, maxiters = 10, smooth_est = true, + step_limiter! = trivial_limiter!) + RadauIIA5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(fast_convergence_cutoff), + typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, + precs, + smooth_est, + extrapolant, + κ, + maxiters, + fast_convergence_cutoff, + new_W_γdt_cutoff, + controller, + step_limiter!) +end +TruncatedStacktraces.@truncate_stacktrace RadauIIA5 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/controllers.jl b/lib/OrdinaryDiffEqFIRK/src/controllers.jl new file mode 100644 index 0000000000..254b1c4436 --- /dev/null +++ b/lib/OrdinaryDiffEqFIRK/src/controllers.jl @@ -0,0 +1,25 @@ +@inline function stepsize_controller!(integrator, controller::PredictiveController, alg) + @unpack qmin, qmax, gamma = integrator.opts + EEst = DiffEqBase.value(integrator.EEst) + + if iszero(EEst) + q = inv(qmax) + else + if fac_default_gamma(alg) + fac = gamma + else + if alg isa Union{RadauIIA3, RadauIIA5} + @unpack iter = integrator.cache + @unpack maxiters = alg + else + @unpack iter, maxiters = integrator.cache.nlsolver + end + fac = min(gamma, (1 + 2 * maxiters) * gamma / (iter + 2 * maxiters)) + end + expo = 1 / (get_current_adaptive_order(alg, integrator.cache) + 1) + qtmp = DiffEqBase.fastpow(EEst, expo) / fac + @fastmath q = DiffEqBase.value(max(inv(qmax), min(inv(qmin), qtmp))) + integrator.qold = q + end + q +end \ No newline at end of file diff --git a/src/caches/firk_caches.jl b/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl similarity index 100% rename from src/caches/firk_caches.jl rename to lib/OrdinaryDiffEqFIRK/src/firk_caches.jl diff --git a/src/perform_step/firk_perform_step.jl b/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl similarity index 99% rename from src/perform_step/firk_perform_step.jl rename to lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl index f49444eff4..2ceadc20a1 100644 --- a/src/perform_step/firk_perform_step.jl +++ b/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl @@ -748,4 +748,4 @@ end f(fsallast, u, p, t + dt) integrator.stats.nf += 1 return -end +end \ No newline at end of file diff --git a/src/tableaus/firk_tableaus.jl b/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl similarity index 99% rename from src/tableaus/firk_tableaus.jl rename to lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl index 85db091bb7..c14cd7eab2 100644 --- a/src/tableaus/firk_tableaus.jl +++ b/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl @@ -109,4 +109,4 @@ function RadauIIA5Tableau(T, T2) c1, c2, #= c3 = 1 =# γ, α, β, e1, e2, e3) -end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl b/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl new file mode 100644 index 0000000000..ced31522bf --- /dev/null +++ b/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl @@ -0,0 +1,4 @@ +@inline function DiffEqBase.get_tmp_cache(integrator, alg::Union{RadauIIA3, RadauIIA5}, + cache::OrdinaryDiffEqMutableCache) + (cache.tmp, cache.atmp) +end \ No newline at end of file diff --git a/test/algconvergence/ode_firk_tests.jl b/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl similarity index 99% rename from test/algconvergence/ode_firk_tests.jl rename to lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl index ade18509a8..562929c255 100644 --- a/test/algconvergence/ode_firk_tests.jl +++ b/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl @@ -51,4 +51,4 @@ for iip in (true, false) @test sol.stats.njacs < sol.stats.nw # W reuse end @test length(sol) < 5000 # the error estimate is not very good -end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/test/runtests.jl b/lib/OrdinaryDiffEqFIRK/test/runtests.jl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml new file mode 100644 index 0000000000..76bfd6e5be --- /dev/null +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -0,0 +1,4 @@ +name = "OrdinaryDiffEqSDIRK" +uuid = "b2cb2727-2d56-444c-bf6a-1484cae16977" +authors = ["ParamThakkar123 "] +version = "1.0.0" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl new file mode 100644 index 0000000000..b378fa6ee4 --- /dev/null +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -0,0 +1,5 @@ +module OrdinaryDiffEqSDIRK + +greet() = print("Hello World!") + +end # module OrdinaryDiffEqSDIRK diff --git a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl new file mode 100644 index 0000000000..384dd7dea8 --- /dev/null +++ b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl @@ -0,0 +1,47 @@ +alg_extrapolates(alg::SDIRK22) = true +alg_extrapolates(alg::ImplicitEuler) = true +alg_extrapolates(alg::Trapezoid) = true + +alg_adaptive_order(alg::ImplicitEuler) = 0 +alg_adaptive_order(alg::ImplicitMidpoint) = 1 +alg_adaptive_order(alg::Trapezoid) = 1 + +alg_order(alg::TRBDF2) = 2 +alg_order(alg::ImplicitEuler) = 1 +alg_order(alg::Trapezoid) = 2 +alg_order(alg::ImplicitMidpoint) = 2 +alg_order(alg::SSPSDIRK2) = 2 +alg_order(alg::KenCarp3) = 3 +alg_order(alg::CFNLIRK3) = 3 +alg_order(alg::SDIRK2) = 2 +alg_order(alg::SDIRK22) = 2 +alg_order(alg::ESDIRK54I8L2SA) = 5 +alg_order(alg::ESDIRK436L2SA2) = 4 +alg_order(alg::ESDIRK437L2SA) = 4 +alg_order(alg::Kvaerno3) = 3 +alg_order(alg::ESDIRK547L2SA2) = 5 +alg_order(alg::ESDIRK659L2SA) = 6 +alg_order(alg::SFSDIRK4) = 4 +alg_order(alg::SFSDIRK5) = 4 +alg_order(alg::SFSDIRK6) = 4 +alg_order(alg::SFSDIRK7) = 4 +alg_order(alg::SFSDIRK8) = 4 +alg_order(alg::Cash4) = 4 +alg_order(alg::Hairer4) = 4 +alg_order(alg::Hairer42) = 4 +alg_order(alg::Kvaerno4) = 4 +alg_order(alg::Kvaerno5) = 5 +alg_order(alg::KenCarp4) = 4 +alg_order(alg::KenCarp47) = 4 +alg_order(alg::KenCarp5) = 5 +alg_order(alg::KenCarp58) = 5 + +ssp_coefficient(alg::SSPSDIRK2) = 4 + +isesdirk(alg::TRBDF2) = true +function isesdirk(alg::Union{KenCarp3, KenCarp4, KenCarp5, KenCarp58, + Kvaerno3, Kvaerno4, Kvaerno5, ESDIRK437L2SA, + ESDIRK54I8L2SA, ESDIRK436L2SA2, ESDIRK547L2SA2, + ESDIRK659L2SA, CFNLIRK3}) + true +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl new file mode 100644 index 0000000000..2442b77ad5 --- /dev/null +++ b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl @@ -0,0 +1,864 @@ +# SDIRK Methods +""" +ImplicitEuler: SDIRK Method +A 1st order implicit solver. A-B-L-stable. Adaptive timestepping through a divided differences estimate via memory. +Strong-stability preserving (SSP). +""" +struct ImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function ImplicitEuler(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :PI, step_limiter! = trivial_limiter!) + ImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, precs, extrapolant, controller, step_limiter!) +end + +""" +ImplicitMidpoint: SDIRK Method +A second order A-stable symplectic and symmetric implicit solver. +Good for highly stiff equations which need symplectic integration. +""" +struct ImplicitMidpoint{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + step_limiter!::StepLimiter +end + +function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, step_limiter! = trivial_limiter!) + ImplicitMidpoint{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + step_limiter!) +end + +""" +Andre Vladimirescu. 1994. The Spice Book. John Wiley & Sons, Inc., New York, +NY, USA. + +Trapezoid: SDIRK Method +A second order A-stable symmetric ESDIRK method. +"Almost symplectic" without numerical dampening. +Also known as Crank-Nicolson when applied to PDEs. Adaptive timestepping via divided +differences approximation to the second derivative terms in the local truncation error +estimate (the SPICE approximation strategy). +""" +struct Trapezoid{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function Trapezoid(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + controller, + step_limiter!) +end + +""" +@article{hosea1996analysis, +title={Analysis and implementation of TR-BDF2}, +author={Hosea, ME and Shampine, LF}, +journal={Applied Numerical Mathematics}, +volume={20}, +number={1-2}, +pages={21--37}, +year={1996}, +publisher={Elsevier} +} + +TRBDF2: SDIRK Method +A second order A-B-L-S-stable one-step ESDIRK method. +Includes stiffness-robust error estimates for accurate adaptive timestepping, smoothed derivatives for highly stiff and oscillatory problems. +""" +struct TRBDF2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function TRBDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + TRBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace TRBDF2 + +""" +@article{hindmarsh2005sundials, +title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, +author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, +journal={ACM Transactions on Mathematical Software (TOMS)}, +volume={31}, +number={3}, +pages={363--396}, +year={2005}, +publisher={ACM} +} + +SDIRK2: SDIRK Method +An A-B-L stable 2nd order SDIRK method +""" +struct SDIRK2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function SDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + SDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}( + linsolve, nlsolve, precs, smooth_est, extrapolant, + controller, + step_limiter!) +end + +struct SDIRK22{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function SDIRK22(; + chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + controller, + step_limiter!) +end + +struct SSPSDIRK2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} # Not adaptive + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end + +function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :constant, + controller = :PI) + SSPSDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno3: SDIRK Method +An A-L stable stiffly-accurate 3rd order ESDIRK method +""" +struct Kvaerno3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp3: SDIRK Method +An A-L stable stiffly-accurate 3rd order ESDIRK method with splitting +""" +struct KenCarp3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +struct CFNLIRK3{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function CFNLIRK3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + CFNLIRK3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +""" +@article{hindmarsh2005sundials, +title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, +author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, +journal={ACM Transactions on Mathematical Software (TOMS)}, +volume={31}, +number={3}, +pages={363--396}, +year={2005}, +publisher={ACM} +} + +Cash4: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Cash4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + embedding::Int + controller::Symbol +end +function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, embedding = 3) + Cash4{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( + linsolve, + nlsolve, + precs, + smooth_est, + extrapolant, + embedding, + controller) +end + +struct SFSDIRK4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function SFSDIRK4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK5{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK6{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK6(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK6{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK7{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK7(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK7{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK8{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK8(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK8{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +""" +E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and +differential-algebraic problems. Computational mathematics (2nd revised ed.), +Springer (1996) + +Hairer4: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Hairer4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function Hairer4(; + chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + Hairer4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and +differential-algebraic problems. Computational mathematics (2nd revised ed.), +Springer (1996) + +Hairer42: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Hairer42{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function Hairer42(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + Hairer42{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno4: SDIRK Method +An A-L stable stiffly-accurate 4th order ESDIRK method. +""" +struct Kvaerno4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno5: SDIRK Method +An A-L stable stiffly-accurate 5th order ESDIRK method +""" +struct Kvaerno5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp4: SDIRK Method +An A-L stable stiffly-accurate 4th order ESDIRK method with splitting +""" +struct KenCarp4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace KenCarp4 + +""" +@article{kennedy2019higher, +title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, +author={Kennedy, Christopher A and Carpenter, Mark H}, +journal={Applied Numerical Mathematics}, +volume={136}, +pages={183--205}, +year={2019}, +publisher={Elsevier} +} + +KenCarp47: SDIRK Method +An A-L stable stiffly-accurate 4th order seven-stage ESDIRK method with splitting +""" +struct KenCarp47{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function KenCarp47(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + KenCarp47{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp5: SDIRK Method +An A-L stable stiffly-accurate 5th order ESDIRK method with splitting +""" +struct KenCarp5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@article{kennedy2019higher, +title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, +author={Kennedy, Christopher A and Carpenter, Mark H}, +journal={Applied Numerical Mathematics}, +volume={136}, +pages={183--205}, +year={2019}, +publisher={Elsevier} +} + +KenCarp58: SDIRK Method +An A-L stable stiffly-accurate 5th order eight-stage ESDIRK method with splitting +""" +struct KenCarp58{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function KenCarp58(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + KenCarp58{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +# `smooth_est` is not necessary, as the embedded method is also L-stable +struct ESDIRK54I8L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK54I8L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK436L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK436L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK437L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK437L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK547L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK547L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} + +Currently has STABILITY ISSUES, causing it to fail the adaptive tests. +Check issue https://github.com/SciML/OrdinaryDiffEq.jl/issues/1933 for more details. +} +""" +struct ESDIRK659L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK659L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end \ No newline at end of file diff --git a/src/caches/kencarp_kvaerno_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl similarity index 99% rename from src/caches/kencarp_kvaerno_caches.jl rename to lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl index e239a42f10..0af6130b8b 100644 --- a/src/caches/kencarp_kvaerno_caches.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl @@ -639,4 +639,4 @@ function alg_cache(alg::KenCarp58, u, rate_prototype, ::Type{uEltypeNoUnits}, KenCarp58Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, k1, k2, k3, k4, k5, k6, k7, k8, atmp, nlsolver, tab) -end +end \ No newline at end of file diff --git a/src/perform_step/kencarp_kvaerno_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl similarity index 99% rename from src/perform_step/kencarp_kvaerno_perform_step.jl rename to lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl index 1b3d6f1a7b..bd43f4faea 100644 --- a/src/perform_step/kencarp_kvaerno_perform_step.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl @@ -2662,4 +2662,4 @@ end else @.. broadcast=false integrator.fsallast=z₈ / dt end -end +end \ No newline at end of file diff --git a/src/caches/sdirk_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl similarity index 99% rename from src/caches/sdirk_caches.jl rename to lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl index 5664341626..eafca44bd1 100644 --- a/src/caches/sdirk_caches.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl @@ -995,4 +995,4 @@ function alg_cache(alg::ESDIRK659L2SA, u, rate_prototype, ::Type{uEltypeNoUnits} nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) ESDIRK659L2SAConstantCache(nlsolver, tab) -end +end \ No newline at end of file diff --git a/src/perform_step/sdirk_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl similarity index 99% rename from src/perform_step/sdirk_perform_step.jl rename to lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl index d94bf0085f..84db426936 100644 --- a/src/perform_step/sdirk_perform_step.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl @@ -3151,4 +3151,4 @@ end @.. broadcast=false integrator.fsallast=z₉ / dt return -end +end \ No newline at end of file diff --git a/src/tableaus/sdirk_tableaus.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl similarity index 99% rename from src/tableaus/sdirk_tableaus.jl rename to lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl index ed95cef957..f008557fda 100644 --- a/src/tableaus/sdirk_tableaus.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl @@ -2773,4 +2773,4 @@ function KenCarp58Tableau(T, T2) ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, ea85, ea86, ea87, eb3, eb4, eb5, eb6, eb7, eb8, ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8) -end +end \ No newline at end of file diff --git a/lib/OrdinaryHighOrderRK/Project.toml b/lib/OrdinaryHighOrderRK/Project.toml new file mode 100644 index 0000000000..fcbd66bf1b --- /dev/null +++ b/lib/OrdinaryHighOrderRK/Project.toml @@ -0,0 +1,4 @@ +name = "OrdinaryDiffEqHighOrderRK" +uuid = "3383601e-94d4-44bc-9605-458335d811d3" +authors = ["ParamThakkar123 "] +version = "1.0.0" diff --git a/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl b/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl new file mode 100644 index 0000000000..d6be00d8f3 --- /dev/null +++ b/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl @@ -0,0 +1,5 @@ +module OrdinaryHighOrderRK + +greet() = print("Hello World!") + +end # module OrdinaryHighOrderRK diff --git a/lib/OrdinaryHighOrderRK/src/alg_utils.jl b/lib/OrdinaryHighOrderRK/src/alg_utils.jl new file mode 100644 index 0000000000..b86634596f --- /dev/null +++ b/lib/OrdinaryHighOrderRK/src/alg_utils.jl @@ -0,0 +1,11 @@ +alg_order(alg::TanYam7) = 7 +alg_order(alg::TsitPap8) = 8 +alg_order(alg::PFRK87) = 8 +alg_order(alg::DP8) = 8 + +beta2_default(alg::DP8) = 0 // 1 +beta1_default(alg::DP8, beta2) = typeof(beta2)(1 // alg_order(alg)) - beta2 / 5 + +qmin_default(alg::DP8) = 1 // 3 + +qmax_default(alg::DP8) = 6 \ No newline at end of file diff --git a/lib/OrdinaryHighOrderRK/src/algorithms.jl b/lib/OrdinaryHighOrderRK/src/algorithms.jl new file mode 100644 index 0000000000..ef8aa3fdae --- /dev/null +++ b/lib/OrdinaryHighOrderRK/src/algorithms.jl @@ -0,0 +1,61 @@ +@doc explicit_rk_docstring( + "Tanaka-Yamashita 7 Runge-Kutta method. (7th order interpolant).", + "TanYam7", + references = "Tanaka M., Muramatsu S., Yamashita S., (1992), On the Optimization of Some Nine-Stage + Seventh-order Runge-Kutta Method, Information Processing Society of Japan, + 33 (12), pp. 1512-1526.") +Base.@kwdef struct TanYam7{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function TanYam7(stage_limiter!, step_limiter! = trivial_limiter!) + TanYam7(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Hairer's 8/5/3 adaption of the Dormand-Prince Runge-Kutta method. (7th order interpolant).", + "DP8", + references = "E. Hairer, S.P. Norsett, G. Wanner, (1993) Solving Ordinary Differential Equations I. + Nonstiff Problems. 2nd Edition. Springer Series in Computational Mathematics, + Springer-Verlag.") +Base.@kwdef struct DP8{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function DP8(stage_limiter!, step_limiter! = trivial_limiter!) + DP8(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("Tsitouras-Papakostas 8/7 Runge-Kutta method.", "TsitPap8") +Base.@kwdef struct TsitPap8{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function TsitPap8(stage_limiter!, step_limiter! = trivial_limiter!) + TsitPap8(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("Phase-fitted Runge-Kutta of 8th order.", "PFRK87", + extra_keyword_description = """- `omega`: a periodicity phase estimate, + when accurate this method results in zero numerical dissipation. + """, + extra_keyword_default = "omega = 0.0") +Base.@kwdef struct PFRK87{StageLimiter, StepLimiter, Thread, T} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + omega::T = 0.0 +end +# for backwards compatibility +function PFRK87(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) + PFRK87(stage_limiter!, step_limiter!, False(), omega) +end \ No newline at end of file diff --git a/src/dense/high_order_rk_addsteps.jl b/lib/OrdinaryHighOrderRK/src/high_order_rk_addsteps.jl similarity index 99% rename from src/dense/high_order_rk_addsteps.jl rename to lib/OrdinaryHighOrderRK/src/high_order_rk_addsteps.jl index 69d14ef78c..5e1447fb24 100644 --- a/src/dense/high_order_rk_addsteps.jl +++ b/lib/OrdinaryHighOrderRK/src/high_order_rk_addsteps.jl @@ -256,4 +256,4 @@ end end end end -=# +=# \ No newline at end of file diff --git a/src/caches/high_order_rk_caches.jl b/lib/OrdinaryHighOrderRK/src/high_order_rk_caches.jl similarity index 99% rename from src/caches/high_order_rk_caches.jl rename to lib/OrdinaryHighOrderRK/src/high_order_rk_caches.jl index bfb55ef511..678ee8416f 100644 --- a/src/caches/high_order_rk_caches.jl +++ b/lib/OrdinaryHighOrderRK/src/high_order_rk_caches.jl @@ -262,4 +262,4 @@ function alg_cache(alg::PFRK87, u, rate_prototype, ::Type{uEltypeNoUnits}, dt, reltol, p, calck, ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} PFRK87ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end +end \ No newline at end of file diff --git a/src/perform_step/high_order_rk_perform_step.jl b/lib/OrdinaryHighOrderRK/src/high_order_rk_perform_step.jl similarity index 99% rename from src/perform_step/high_order_rk_perform_step.jl rename to lib/OrdinaryHighOrderRK/src/high_order_rk_perform_step.jl index 62e6025575..9873cc8cbf 100644 --- a/src/perform_step/high_order_rk_perform_step.jl +++ b/lib/OrdinaryHighOrderRK/src/high_order_rk_perform_step.jl @@ -1150,4 +1150,4 @@ end f(k, u, p, t + dt) integrator.stats.nf += 1 return nothing -end +end \ No newline at end of file diff --git a/src/tableaus/high_order_rk_tableaus.jl b/lib/OrdinaryHighOrderRK/src/high_order_rk_tableaus.jl similarity index 99% rename from src/tableaus/high_order_rk_tableaus.jl rename to lib/OrdinaryHighOrderRK/src/high_order_rk_tableaus.jl index 1e03a14aac..8ca15f91de 100644 --- a/src/tableaus/high_order_rk_tableaus.jl +++ b/lib/OrdinaryHighOrderRK/src/high_order_rk_tableaus.jl @@ -1403,4 +1403,4 @@ function PFRK87ConstantCache(T1::Type, T2::Type) α1211, α1311, β1, β6, β7, β8, β9, β10, β11, β12, β13, β1tilde, β6tilde, β7tilde, β8tilde, β9tilde, β10tilde, β11tilde, β12tilde, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) -end +end \ No newline at end of file diff --git a/lib/OrdinaryHighOrderRK/src/interp_func.jl b/lib/OrdinaryHighOrderRK/src/interp_func.jl new file mode 100644 index 0000000000..6be33c0ada --- /dev/null +++ b/lib/OrdinaryHighOrderRK/src/interp_func.jl @@ -0,0 +1,6 @@ +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{DP8ConstantCache, DP8Cache}} + dense ? "specialized 7th order interpolation" : "1st order linear" +end \ No newline at end of file diff --git a/lib/OrdinaryHighOrderRK/src/interpolants.jl b/lib/OrdinaryHighOrderRK/src/interpolants.jl new file mode 100644 index 0000000000..206dfa9293 --- /dev/null +++ b/lib/OrdinaryHighOrderRK/src/interpolants.jl @@ -0,0 +1,138 @@ +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) +Θ1 = 1 - Θ +# return @.. broadcast=false y₀ + dt*Θ*(k[1] + Θ1*(k[2] + Θ*(k[3]+Θ1*(k[4] + Θ*(k[5] + Θ1*(k[6]+Θ*k[7])))))) +return @inbounds y₀ + + dt * Θ * + (k[1] + + Θ1 * (k[2] + + Θ * (k[3] + Θ1 * (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) +Θ1 = 1 - Θ +# return @.. broadcast=false y₀[idxs] + dt*Θ*(k[1][idxs] + Θ1*(k[2][idxs] + Θ*(k[3][idxs]+Θ1*(k[4][idxs] + Θ*(k[5][idxs] + Θ1*(k[6][idxs]+Θ*k[7][idxs])))))) +return y₀[idxs] + + dt * Θ * + (k[1][idxs] + + Θ1 * (k[2][idxs] + + Θ * (k[3][idxs] + + Θ1 * (k[4][idxs] + Θ * (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + Θ1 = 1 - Θ + @inbounds @.. broadcast=false out=y₀ + + dt * Θ * + (k[1] + + Θ1 * (k[2] + + Θ * (k[3] + + Θ1 * + (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + Θ1 = 1 - Θ + @views @.. broadcast=false out=y₀[idxs] + + dt * Θ * + (k[1][idxs] + + Θ1 * (k[2][idxs] + + Θ * (k[3][idxs] + + Θ1 * (k[4][idxs] + + Θ * + (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) + #end + out +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @inbounds b1diff = @.. broadcast=false k[1]+k[2] + @inbounds b2diff = @.. broadcast=false -2*k[2]+2*k[3]+2*k[4] + @inbounds b3diff = @.. broadcast=false -3 * k[3]-6 * k[4]+3*k[5]+3*k[6] + @inbounds b4diff = @.. broadcast=false 4 * k[4] - 8 * k[5] - 12 * k[6]+4 * k[7] + @inbounds b5diff = @.. broadcast=false 5 * k[5] + 15 * k[6]-15 * k[7] + @inbounds b6diff = @.. broadcast=false -6 * k[6]+18 * k[7] + @inbounds b7diff = @.. broadcast=false -7*k[7] + # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) + return b1diff + + Θ * + (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + b1diff = @.. broadcast=false k[1][idxs]+k[2][idxs] + b2diff = @.. broadcast=false -2*k[2][idxs]+2*k[3][idxs]+2*k[4][idxs] + b3diff = @.. broadcast=false -3 * k[3][idxs]-6 * k[4][idxs]+3*k[5][idxs]+3*k[6][idxs] + b4diff = @.. broadcast=false 4 * k[4][idxs] - 8 * k[5][idxs] - + 12 * k[6][idxs]+4 * k[7][idxs] + b5diff = @.. broadcast=false 5 * k[5][idxs] + 15 * k[6][idxs]-15 * k[7][idxs] + b6diff = @.. broadcast=false -6 * k[6][idxs]+18 * k[7][idxs] + b7diff = @.. broadcast=false -7*k[7][idxs] + # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) + return b1diff + + Θ * + (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + # b1diff = k[1] + k[2] + # b2diff = -2*k[2] + 2*k[3] + 2*k[4] + # b3diff = -3*k[3] - 6*k[4] + 3*k[5] + 3*k[6] + # b4diff = 4*k[4] - 8*k[5] - 12*k[6] + 4*k[7] + # b5diff = 5*k[5] + 15*k[6] - 15*k[7] + # b6diff = -6*k[6] + 18*k[7] + # @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + + # Θ*(b5diff + Θ*(b6diff - 7*k[7]*Θ))))) + @views @.. broadcast=false out=k[1] + k[2] + + Θ * (-2 * k[2] + 2 * k[3] + 2 * k[4] + + Θ * (-3 * k[3] - 6 * k[4] + 3 * k[5] + 3 * k[6] + + Θ * (4 * k[4] - 8 * k[5] - 12 * k[6] + 4 * k[7] + + Θ * (5 * k[5] + 15 * k[6] - 15 * k[7] + + Θ * (-6 * k[6] + 18 * k[7] - 7 * k[7] * Θ))))) + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + # b1diff = k[1][idxs] + k[2][idxs] + # b2diff = -2*k[2][idxs] + 2*k[3][idxs] + 2*k[4][idxs] + # b3diff = -3*k[3][idxs] - 6*k[4][idxs] + 3*k[5][idxs] + 3*k[6][idxs] + # b4diff = 4*k[4][idxs] - 8*k[5][idxs] - 12*k[6][idxs] + 4*k[7][idxs] + # b5diff = 5*k[5][idxs] + 15*k[6][idxs] - 15*k[7][idxs] + # b6diff = -6*k[6][idxs] + 18*k[7][idxs] + #@views @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + + # Θ*(b5diff + Θ*(b6diff - 7*k[7][idxs]*Θ))))) + @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] + + Θ * (-2 * k[2][idxs] + 2 * k[3][idxs] + 2 * k[4][idxs] + + Θ * + (-3 * k[3][idxs] - 6 * k[4][idxs] + 3 * k[5][idxs] + + 3 * k[6][idxs] + + Θ * + (4 * k[4][idxs] - 8 * k[5][idxs] - 12 * k[6][idxs] + + 4 * k[7][idxs] + + Θ * + (5 * k[5][idxs] + 15 * k[6][idxs] - 15 * k[7][idxs] + + Θ * (-6 * k[6][idxs] + 18 * k[7][idxs] - + 7 * k[7][idxs] * Θ))))) + out +end \ No newline at end of file diff --git a/lib/OrdinaryLowOrderRK/Project.toml b/lib/OrdinaryLowOrderRK/Project.toml new file mode 100644 index 0000000000..7cb4ff6beb --- /dev/null +++ b/lib/OrdinaryLowOrderRK/Project.toml @@ -0,0 +1,4 @@ +name = "OrdinaryDiffEqLowOrderRK" +uuid = "0e0916b3-e0a4-463e-8dfa-d409d9d724ed" +authors = ["ParamThakkar123 "] +version = "0.1.0" diff --git a/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl b/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl new file mode 100644 index 0000000000..8739bea899 --- /dev/null +++ b/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl @@ -0,0 +1,5 @@ +module OrdinaryLowOrderRK + +greet() = print("Hello World!") + +end # module OrdinaryLowOrderRK diff --git a/lib/OrdinaryLowOrderRK/src/alg_utils.jl b/lib/OrdinaryLowOrderRK/src/alg_utils.jl new file mode 100644 index 0000000000..6cfdd74af8 --- /dev/null +++ b/lib/OrdinaryLowOrderRK/src/alg_utils.jl @@ -0,0 +1,47 @@ +alg_order(alg::Heun) = 2 +alg_order(alg::Euler) = 1 +alg_order(alg::Ralston) = 2 +alg_order(alg::SplitEuler) = 1 +alg_order(alg::Midpoint) = 2 +alg_order(alg::RK4) = 4 +alg_order(alg::BS3) = 3 +alg_order(alg::OwrenZen3) = 3 +alg_order(alg::OwrenZen4) = 4 +alg_order(alg::OwrenZen5) = 5 +alg_order(alg::BS5) = 5 +alg_order(alg::Tsit5) = 5 +alg_order(alg::DP5) = 5 +alg_order(alg::Anas5) = 5 +alg_order(alg::RKO65) = 5 +alg_order(alg::FRK65) = 6 +alg_order(alg::RKM) = 4 +alg_order(alg::MSRK6) = 6 +alg_order(alg::MSRK5) = 5 +alg_order(alg::PSRK4p7q6) = 4 +alg_order(alg::PSRK3p6q5) = 3 +alg_order(alg::Stepanov5) = 5 +alg_order(alg::SIR54) = 5 +alg_order(alg::Alshina2) = 2 +alg_order(alg::Alshina3) = 3 +alg_order(alg::Alshina6) = 6 +alg_order(alg::PSRK3p5q4) = 3 +alg_order(alg::FunctionMap) = 0 + +isfsal(alg::FunctionMap) = false +isfsal(alg::RKO65) = false +isfsal(alg::FRK65) = true +isfsal(alg::PSRK3p5q4) = false +isfsal(alg::RKM) = false +isfsal(alg::PSRK4p7q6) = false +isfsal(alg::PSRK3p6q5) = false + +beta2_default(alg::DP5) = 4 // 100 +beta2_default(alg::FunctionMap) = 0 + +beta1_default(alg::DP5, beta2) = typeof(beta2)(1 // alg_order(alg)) - 3beta2 / 4 +beta1_default(alg::FunctionMap, beta2) = 0 + +alg_stability_size(alg::Tsit5) = 3.5068 +alg_stability_size(alg::DP5) = 3.3066 + +ssp_coefficient(alg::Euler) = 1 \ No newline at end of file diff --git a/lib/OrdinaryLowOrderRK/src/algorithms.jl b/lib/OrdinaryLowOrderRK/src/algorithms.jl new file mode 100644 index 0000000000..f71127bd91 --- /dev/null +++ b/lib/OrdinaryLowOrderRK/src/algorithms.jl @@ -0,0 +1,632 @@ +@doc explicit_rk_docstring( + "The second order Heun's method. Uses embedded Euler method for adaptivity.", + "Heun") +Base.@kwdef struct Heun{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Heun(stage_limiter!, step_limiter! = trivial_limiter!) + Heun(stage_limiter!, step_limiter!, False()) +end + +struct SplitEuler <: + OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end + +struct Euler <: OrdinaryDiffEqAlgorithm end + +@doc explicit_rk_docstring( + "The optimized second order midpoint method. Uses embedded Euler method for adaptivity.", + "Ralston") +Base.@kwdef struct Ralston{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Ralston(stage_limiter!, step_limiter! = trivial_limiter!) + Ralston(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "The second order midpoint method. Uses embedded Euler method for adaptivity.", + "Midpoint") +Base.@kwdef struct Midpoint{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Midpoint(stage_limiter!, step_limiter! = trivial_limiter!) + Midpoint(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("The canonical Runge-Kutta Order 4 method. +Uses a defect control for adaptive stepping using maximum error over the whole interval.", + "RK4", + references = "@article{shampine2005solving, + title={Solving ODEs and DDEs with residual control}, + author={Shampine, LF}, + journal={Applied Numerical Mathematics}, + volume={52}, + number={1}, + pages={113--127}, + year={2005}, + publisher={Elsevier} + }") +Base.@kwdef struct RK4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function RK4(stage_limiter!, step_limiter! = trivial_limiter!) + RK4(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "A third-order, four-stage explicit FSAL Runge-Kutta method with embedded error +estimator of Bogacki and Shampine.", + "BS3", + references = "@article{bogacki19893, + title={A 3 (2) pair of Runge-Kutta formulas}, + author={Bogacki, Przemyslaw and Shampine, Lawrence F}, + journal={Applied Mathematics Letters}, + volume={2}, + number={4}, + pages={321--325}, + year={1989}, + publisher={Elsevier} + }") +Base.@kwdef struct BS3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function BS3(stage_limiter!, step_limiter! = trivial_limiter!) + BS3(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Owren-Zennaro optimized interpolation 3/2 method (free 3rd order interpolant).", + "OwrenZen3", + references = "@article{owren1992derivation, + title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, + author={Owren, Brynjulf and Zennaro, Marino}, + journal={SIAM journal on scientific and statistical computing}, + volume={13}, + number={6}, + pages={1488--1501}, + year={1992}, + publisher={SIAM} + }") +Base.@kwdef struct OwrenZen3{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function OwrenZen3(stage_limiter!, step_limiter! = trivial_limiter!) + OwrenZen3(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Owren-Zennaro optimized interpolation 4/3 method (free 4th order interpolant).", + "OwrenZen4", + references = "@article{owren1992derivation, + title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, + author={Owren, Brynjulf and Zennaro, Marino}, + journal={SIAM journal on scientific and statistical computing}, + volume={13}, + number={6}, + pages={1488--1501}, + year={1992}, + publisher={SIAM} + }") +Base.@kwdef struct OwrenZen4{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function OwrenZen4(stage_limiter!, step_limiter! = trivial_limiter!) + OwrenZen4(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Owren-Zennaro optimized interpolation 5/4 method (free 5th order interpolant).", + "OwrenZen5", + references = "@article{owren1992derivation, + title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, + author={Owren, Brynjulf and Zennaro, Marino}, + journal={SIAM journal on scientific and statistical computing}, + volume={13}, + number={6}, + pages={1488--1501}, + year={1992}, + publisher={SIAM} + }") +Base.@kwdef struct OwrenZen5{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function OwrenZen5(stage_limiter!, step_limiter! = trivial_limiter!) + OwrenZen5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Bogacki-Shampine 5/4 Runge-Kutta method. (lazy 5th order interpolant).", + "BS5", + references = "@article{bogacki1996efficient, + title={An efficient runge-kutta (4, 5) pair}, + author={Bogacki, P and Shampine, Lawrence F}, + journal={Computers \\& Mathematics with Applications}, + volume={32}, + number={6}, + pages={15--28}, + year={1996}, + publisher={Elsevier} + }", + extra_keyword_description = """- `lazy`: determines if the lazy interpolant is used. + """, + extra_keyword_default = "lazy = true") +Base.@kwdef struct BS5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + lazy::Bool = true +end +# for backwards compatibility +function BS5(stage_limiter!, step_limiter! = trivial_limiter!; lazy = true) + BS5(stage_limiter!, step_limiter!, False(), lazy) +end + +@doc explicit_rk_docstring( + "A fifth-order explicit Runge-Kutta method with embedded error +estimator of Tsitouras. Free 4th order interpolant.", "Tsit5", + references = "@article{tsitouras2011runge, + title={Runge--Kutta pairs of order 5 (4) satisfying only the first column simplifying assumption}, + author={Tsitouras, Ch}, + journal={Computers \\& Mathematics with Applications}, + volume={62}, + number={2}, + pages={770--775}, + year={2011}, + publisher={Elsevier} + }") +Base.@kwdef struct Tsit5{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +TruncatedStacktraces.@truncate_stacktrace Tsit5 3 +# for backwards compatibility +function Tsit5(stage_limiter!, step_limiter! = trivial_limiter!) + Tsit5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Dormand-Prince's 5/4 Runge-Kutta method. (free 4th order interpolant).", + "DP5", + references = "@article{dormand1980family, + title={A family of embedded Runge-Kutta formulae}, + author={Dormand, John R and Prince, Peter J}, + journal={Journal of computational and applied mathematics}, + volume={6}, + number={1}, + pages={19--26}, + year={1980}, + publisher={Elsevier} + }") +Base.@kwdef struct DP5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function DP5(stage_limiter!, step_limiter! = trivial_limiter!) + DP5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("4th order Runge-Kutta method designed for periodic problems.", + "Anas5", + extra_keyword_description = """- `w`: a periodicity estimate, which when accurate the method becomes 5th order + (and is otherwise 4th order with less error for better estimates). + """, + extra_keyword_default = "w = 1") +Base.@kwdef struct Anas5{StageLimiter, StepLimiter, Thread, T} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + w::T = 1 +end +# for backwards compatibility +function Anas5(stage_limiter!, step_limiter! = trivial_limiter!; w = 1) + Anas5(stage_limiter!, step_limiter!, False(), w) +end + +@doc explicit_rk_docstring("5th order Explicit RK method.", "RKO5", + references = "Tsitouras, Ch. \"Explicit Runge–Kutta methods for starting integration of + Lane–Emden problem.\" Applied Mathematics and Computation 354 (2019): 353-364. + doi: https://doi.org/10.1016/j.amc.2019.02.047") +Base.@kwdef struct RKO65{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function RKO65(stage_limiter!, step_limiter! = trivial_limiter!) + RKO65(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("Zero Dissipation Runge-Kutta of 6th order.", "FRK65", + extra_keyword_description = """- `omega`: a periodicity phase estimate, + when accurate this method results in zero numerical dissipation. + """, + extra_keyword_default = "omega = 0.0") +Base.@kwdef struct FRK65{StageLimiter, StepLimiter, Thread, T} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + omega::T = 0.0 +end + +# for backwards compatibility +function FRK65(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) + FRK65(stage_limiter!, step_limiter!, False(), omega) +end + +@doc explicit_rk_docstring("TBD", "RKM") +Base.@kwdef struct RKM{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function RKM(stage_limiter!, step_limiter! = trivial_limiter!) + RKM(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("5th order Explicit RK method.", "MSRK5", + references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Figure 3.") +Base.@kwdef struct MSRK5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function MSRK5(stage_limiter!, step_limiter! = trivial_limiter!) + MSRK5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("6th order Explicit RK method.", "MSRK6", + references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Table4") +Base.@kwdef struct MSRK6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function MSRK6(stage_limiter!, step_limiter! = trivial_limiter!) + MSRK6(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("6-stage Pseudo-Symplectic Explicit RK method.", "4p7q(6)", + references = "@article{Aubry1998, + author = {A. Aubry and P. Chartier}, + journal = {BIT Numer. Math.}, + title = {Pseudo-symplectic {R}unge-{K}utta methods}, + volume = {38}, + PAGES = {439-461}, + year = {1998}, + }, + @article{Capuano2017, + title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, + journal = {J. Comput. Phys.}, + volume = {328}, + pages = {86-94}, + year = {2017}, + issn = {0021-9991}, + doi = {https://doi.org/10.1016/j.jcp.2016.10.040}, + author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") +Base.@kwdef struct PSRK4p7q6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end + +@doc explicit_rk_docstring("5-stage Pseudo-Symplectic Explicit RK method.", "3p6q(5)", + references = "@article{Aubry1998, + author = {A. Aubry and P. Chartier}, + journal = {BIT Numer. Math.}, + title = {Pseudo-symplectic {R}unge-{K}utta methods}, + year = {1998}, + }, + @article{Capuano2017, + title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, + journal = {J. Comput. Phys.}, + year = {2017}, + author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") +Base.@kwdef struct PSRK3p6q5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end + +@doc explicit_rk_docstring("5th order Explicit RK method.", + "Stepanov5", + references = "@article{Stepanov2021Embedded5, + title={Embedded (4, 5) pairs of explicit 7-stage Runge–Kutta methods with FSAL property}, + author={Misha Stepanov}, + journal={Calcolo}, + year={2021}, + volume={59} + }") +Base.@kwdef struct Stepanov5{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Stepanov5(stage_limiter!, step_limiter! = trivial_limiter!) + Stepanov5(stage_limiter!, step_limiter!, False()) +end + +@inline trivial_limiter!(u, integrator, p, t) = nothing +""" + SIR54(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +5th order Explicit RK method suited for SIR-type epidemic models. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Kovalnogov2020RungeKuttaPS, +title={Runge–Kutta pairs suited for SIR‐type epidemic models}, +author={Vladislav N. Kovalnogov and Theodore E. Simos and Ch. Tsitouras}, +journal={Mathematical Methods in the Applied Sciences}, +year={2020}, +volume={44}, +pages={5210 - 5216} +} +""" +struct SIR54{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function SIR54(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + SIR54{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +# for backwards compatibility +function SIR54(stage_limiter!, step_limiter! = trivial_limiter!) + SIR54{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::SIR54) + print(io, "SIR54(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + +""" + Alshina2(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +2nd order, 2-stage Explicit Runge-Kutta Method with optimal parameters. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Alshina2008, +doi = {10.1134/s0965542508030068}, +url = {https://doi.org/10.1134/s0965542508030068}, +year = {2008}, +month = mar, +publisher = {Pleiades Publishing Ltd}, +volume = {48}, +number = {3}, +pages = {395--405}, +author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, +title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, +journal = {Computational Mathematics and Mathematical Physics} +} +""" +struct Alshina2{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function Alshina2(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + Alshina2{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +function Alshina2(stage_limiter!, step_limiter! = trivial_limiter!) + Alshina2{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::Alshina2) + print(io, "Alshina2(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + +""" + Alshina3(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +3rd order, 3-stage Explicit Runge-Kutta Method with optimal parameters. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Alshina2008, +doi = {10.1134/s0965542508030068}, +url = {https://doi.org/10.1134/s0965542508030068}, +year = {2008}, +month = mar, +publisher = {Pleiades Publishing Ltd}, +volume = {48}, +number = {3}, +pages = {395--405}, +author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, +title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, +journal = {Computational Mathematics and Mathematical Physics} +} +""" +struct Alshina3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function Alshina3(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + Alshina3{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +function Alshina3(stage_limiter!, step_limiter! = trivial_limiter!) + Alshina3{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::Alshina3) + print(io, "Alshina3(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + +""" + Alshina6(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +6th order, 7-stage Explicit Runge-Kutta Method with optimal parameters. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Alshina2008, +doi = {10.1134/s0965542508030068}, +url = {https://doi.org/10.1134/s0965542508030068}, +year = {2008}, +month = mar, +publisher = {Pleiades Publishing Ltd}, +volume = {48}, +number = {3}, +pages = {395--405}, +author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, +title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, +journal = {Computational Mathematics and Mathematical Physics} +} +""" +struct Alshina6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function Alshina6(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + Alshina6{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +function Alshina6(stage_limiter!, step_limiter! = trivial_limiter!) + Alshina6{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::Alshina6) + print(io, "Alshina6(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + +@doc explicit_rk_docstring("4-stage Pseudo-Symplectic Explicit RK method.", "3p5q(4)", + references = "@article{Aubry1998, + author = {A. Aubry and P. Chartier}, + journal = {BIT Numer. Math.}, + title = {Pseudo-symplectic {R}unge-{K}utta methods}, + year = {1998}, + }, + @article{Capuano2017, + title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, + journal = {J. Comput. Phys.}, + year = {2017}, + author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") +Base.@kwdef struct PSRK3p5q4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end + +struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end +FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() \ No newline at end of file diff --git a/lib/OrdinaryLowOrderRK/src/fixed_timestep_perform_step.jl b/lib/OrdinaryLowOrderRK/src/fixed_timestep_perform_step.jl new file mode 100644 index 0000000000..46b9746215 --- /dev/null +++ b/lib/OrdinaryLowOrderRK/src/fixed_timestep_perform_step.jl @@ -0,0 +1,487 @@ +function initialize!(integrator, cache::Union{HeunConstantCache, RalstonConstantCache}) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, + cache::Union{HeunConstantCache, RalstonConstantCache}, + repeat_step = false) + @unpack t, dt, uprev, u, f, p, fsalfirst = integrator + + # precalculations + if cache isa HeunConstantCache + a₁ = dt + a₂ = dt / 2 + else # Ralston + a₁ = 2 * dt / 3 + a₂ = dt / 4 + a₃ = 3 * a₂ + end + + tmp = @.. broadcast=false uprev+a₁ * fsalfirst + k2 = f(tmp, p, t + a₁) + integrator.stats.nf += 1 + + if cache isa HeunConstantCache + u = @.. broadcast=false uprev+a₂ * (fsalfirst + k2) + else + u = @.. broadcast=false uprev+a₂*fsalfirst+a₃*k2 + end + + if integrator.opts.adaptive + if cache isa HeunConstantCache + tmp = @.. broadcast=false a₂*(k2 - fsalfirst) + else + tmp = @.. broadcast=false a₃*(k2 - fsalfirst) + end + + atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + k = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.fsallast = k + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::Union{HeunCache, RalstonCache}) + integrator.kshortsize = 2 + @unpack k, fsalfirst = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::Union{HeunCache, RalstonCache}, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack fsalfirst, k, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + + # precalculations + if cache isa HeunCache + a₁ = dt + a₂ = dt / 2 + else # Ralston + a₁ = 2 * dt / 3 + a₂ = dt / 4 + a₃ = 3 * a₂ + end + + @.. broadcast=false thread=thread tmp=uprev + a₁ * fsalfirst + stage_limiter!(tmp, integrator, p, t + a₁) + f(k, tmp, p, t + a₁) + integrator.stats.nf += 1 + + if cache isa HeunCache + @.. broadcast=false thread=thread u=uprev + a₂ * (fsalfirst + k) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + else + @.. broadcast=false thread=thread u=uprev + a₂ * fsalfirst + a₃ * k + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + end + + if integrator.opts.adaptive + if cache isa HeunCache + @.. broadcast=false thread=thread tmp=a₂ * (k - fsalfirst) + else + @.. broadcast=false thread=thread tmp=a₃ * (k - fsalfirst) + end + + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function initialize!(integrator, cache::MidpointCache) + @unpack k, fsalfirst = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # FSAL for interpolation + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::MidpointCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tmp, k, fsalfirst, atmp, stage_limiter!, step_limiter!, thread = cache + halfdt = dt / 2 + @.. broadcast=false thread=thread tmp=uprev + halfdt * fsalfirst + stage_limiter!(k, tmp, p, t + halfdt) + f(k, tmp, p, t + halfdt) + integrator.stats.nf += 1 + @.. broadcast=false thread=thread u=uprev + dt * k + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + if integrator.opts.adaptive + @.. broadcast=false thread=thread tmp=dt * (fsalfirst - k) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + f(k, u, p, t + dt) + integrator.stats.nf += 1 +end + +function initialize!(integrator, cache::Anas5ConstantCache) + integrator.kshortsize = 7 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::Anas5ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache + ## Note that c1 and b2 were 0. + alg = unwrap_alg(integrator, false) + w = alg.w + v = w * dt + ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. + a65 = (-8000 // 1071) * + (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + + 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) + a61 += (-119 // 200) * a65 + a63 += (189 // 100) * a65 + a64 += (-459 // 200) * a65 + k1 = integrator.fsalfirst + k2 = f(uprev + dt * a21 * k1, p, t + c2 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c3 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + 2 * k3), p, t + c4 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c5 * dt) + k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, + t + c6 * dt) + u = uprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) + k7 = f(u, p, t + dt) + integrator.fsallast = k7 + integrator.stats.nf += 6 + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.u = u +end + +function initialize!(integrator, cache::Anas5Cache) + integrator.kshortsize = 7 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k7 # setup pointers + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::Anas5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + uidx = eachindex(integrator.uprev) + @unpack k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache.tab + alg = unwrap_alg(integrator, false) + w = alg.w + v = w * dt + ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. + a65 = (-8000 // 1071) * + (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + + 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) + a61 += (-119 // 200) * a65 + a63 += (189 // 100) * a65 + a64 += (-459 // 200) * a65 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + a21 * k1[i] + end + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + dt * (a31 * k1[i] + a32 * k2[i]) + end + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + dt * (a41 * k1[i] + a42 * k2[i] + 2 * k3[i]) + end + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + + dt * (a51 * k1[i] + a52 * k2[i] + a53 * k3[i] + a54 * k4[i]) + end + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + + dt * (a61 * k1[i] + a62 * k2[i] + a63 * k3[i] + a64 * k4[i] + + a65 * k5[i]) + end + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @tight_loop_macros for i in uidx + @inbounds u[i] = uprev[i] + + dt * + (b1 * k1[i] + b3 * k3[i] + b4 * k4[i] + b5 * k5[i] + b6 * k6[i]) + end + stage_limiter!(tmp, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k7, u, p, t + dt) + integrator.stats.nf += 6 +end + +function initialize!(integrator, cache::RK4ConstantCache) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::RK4ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + halfdt = dt / 2 + k₁ = integrator.fsalfirst + ttmp = t + halfdt + k₂ = f(uprev + halfdt * k₁, p, ttmp) + k₃ = f(uprev + halfdt * k₂, p, ttmp) + k₄ = f(uprev + dt * k₃, p, t + dt) + u = uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 4 + if integrator.opts.adaptive + # Shampine Solving ODEs and DDEs with Residual Control Estimate + k₅ = integrator.fsallast + + # one(t) so that types are correct but unitless + σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 + σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 + p1 = (1 - σ₁) * uprev + σ₁ * u + + σ₁ * (σ₁ - 1) * ((1 - 2σ₁) * (u - uprev) + (σ₁ - 1) * dt * k₁ + σ₁ * dt * k₅) + p2 = (1 - σ₂) * uprev + σ₂ * u + + σ₂ * (σ₂ - 1) * ((1 - 2σ₂) * (u - uprev) + (σ₂ - 1) * dt * k₁ + σ₂ * dt * k₅) + pprime1 = k₁ + + σ₁ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₁ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt + pprime2 = k₁ + + σ₂ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₂ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt + e1 = integrator.opts.internalnorm( + calculate_residuals(dt * (f(p1, p, t + σ₁ * dt) - + pprime1), uprev, u, + integrator.opts.abstol, + integrator.opts.reltol, + integrator.opts.internalnorm, + t), + t) + e2 = integrator.opts.internalnorm( + calculate_residuals(dt * (f(p2, p, t + σ₂ * dt) - + pprime2), uprev, u, + integrator.opts.abstol, + integrator.opts.reltol, + integrator.opts.internalnorm, + t), + t) + integrator.stats.nf += 2 + integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) + end + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::RK4Cache) + @unpack tmp, fsalfirst, k₂, k₃, k₄, k = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # pre-start FSAL + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::RK4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tmp, fsalfirst, k₂, k₃, k₄, k, atmp, stage_limiter!, step_limiter!, thread = cache + k₁ = fsalfirst + halfdt = dt / 2 + ttmp = t + halfdt + @.. broadcast=false thread=thread tmp=uprev + halfdt * k₁ + stage_limiter!(tmp, integrator, p, ttmp) + f(k₂, tmp, p, ttmp) + @.. broadcast=false thread=thread tmp=uprev + halfdt * k₂ + stage_limiter!(tmp, integrator, p, ttmp) + f(k₃, tmp, p, ttmp) + @.. broadcast=false thread=thread tmp=uprev + dt * k₃ + stage_limiter!(tmp, integrator, p, t + dt) + f(k₄, tmp, p, t + dt) + @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k, u, p, t + dt) + integrator.stats.nf += 4 + if integrator.opts.adaptive + # Shampine Solving ODEs and DDEs with Residual Control Estimate + k₅ = k + _p = k₂ + pprime = k₃ # Alias some cache arrays + # one(t) so that types are correct but unitless + σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 + σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 + @.. broadcast=false thread=thread tmp=(1 - σ₁) * uprev + σ₁ * u + + σ₁ * (σ₁ - 1) * + ((1 - 2σ₁) * (u - uprev) + + (σ₁ - 1) * dt * k₁ + + σ₁ * dt * k₅) + @.. broadcast=false thread=thread pprime=k₁ + + σ₁ * + (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₁ * + (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - + 6 * u) + + 6 * u) / dt + f(_p, tmp, p, t + σ₁ * dt) + @.. broadcast=false thread=thread tmp=dt * (_p - pprime) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + e1 = integrator.opts.internalnorm(atmp, t) + @.. broadcast=false thread=thread tmp=(1 - σ₂) * uprev + σ₂ * u + + σ₂ * (σ₂ - 1) * + ((1 - 2σ₂) * (u - uprev) + + (σ₂ - 1) * dt * k₁ + + σ₂ * dt * k₅) + @.. broadcast=false thread=thread pprime=k₁ + + σ₂ * + (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₂ * + (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - + 6 * u) + + 6 * u) / dt + f(_p, tmp, p, t + σ₂ * dt) + @.. broadcast=false thread=thread tmp=dt * (_p - pprime) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + e2 = integrator.opts.internalnorm(atmp, t) + integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) + integrator.stats.nf += 2 + end +end + +function initialize!(integrator, cache::MidpointConstantCache) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::MidpointConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + halfdt = dt / 2 + tmp = @.. broadcast=false uprev+halfdt * integrator.fsalfirst + k = f(tmp, p, t + halfdt) + integrator.stats.nf += 1 + u = @.. broadcast=false uprev+dt * k + integrator.fsallast = f(u, p, t + dt) # For interpolation, then FSAL'd + integrator.stats.nf += 1 + if integrator.opts.adaptive + utilde = @.. broadcast=false dt*(integrator.fsalfirst - k) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::EulerConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::EulerConstantCache, repeat_step = false) + @unpack t, dt, uprev, f, p = integrator + @muladd u = @.. broadcast=false uprev+dt * integrator.fsalfirst + k = f(u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 + integrator.fsallast = k + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::EulerCache) + integrator.kshortsize = 2 + @unpack k, fsalfirst = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::EulerCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @muladd @.. broadcast=false u=uprev + dt * integrator.fsalfirst + f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end \ No newline at end of file diff --git a/lib/OrdinaryLowOrderRK/src/interp_func.jl b/lib/OrdinaryLowOrderRK/src/interp_func.jl new file mode 100644 index 0000000000..1ac8d6c154 --- /dev/null +++ b/lib/OrdinaryLowOrderRK/src/interp_func.jl @@ -0,0 +1,52 @@ +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: Union{OwrenZen3Cache, + OwrenZen3ConstantCache}} + dense ? "specialized 3rd order \"free\" interpolation" : "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: Union{OwrenZen4Cache, + OwrenZen4ConstantCache}} + dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: Union{OwrenZen5Cache, + OwrenZen5ConstantCache}} + dense ? "specialized 5th order \"free\" interpolation" : "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{BS5ConstantCache, BS5Cache}} + dense ? "specialized 5th order lazy interpolation" : "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Tsit5Cache, Tsit5ConstantCache +}} + dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{DP5ConstantCache, DP5Cache}} + dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where {cacheType <: + FunctionMapConstantCache} + "left-endpoint piecewise constant" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where {cacheType <: FunctionMapCache} + "left-endpoint piecewise constant" +end \ No newline at end of file diff --git a/src/dense/interpolants.jl b/lib/OrdinaryLowOrderRK/src/interpolants.jl similarity index 88% rename from src/dense/interpolants.jl rename to lib/OrdinaryLowOrderRK/src/interpolants.jl index ebf6d226bc..ead344d493 100644 --- a/src/dense/interpolants.jl +++ b/lib/OrdinaryLowOrderRK/src/interpolants.jl @@ -1,11 +1,13 @@ -RK_WITH_SPECIAL_INTERPOLATIONS = Union{FunctionMapConstantCache, FunctionMapCache, - DP5ConstantCache, DP5Cache, - Tsit5ConstantCache, Tsit5Cache, +RK_WITH_SPECIAL_INTERPOLATIONS = Union{ OwrenZen3ConstantCache, OwrenZen3Cache, OwrenZen4ConstantCache, OwrenZen4Cache, OwrenZen5ConstantCache, OwrenZen5Cache, - BS5ConstantCache, BS5Cache + DP5ConstantCache, DP5Cache, + Tsit5ConstantCache, Tsit5Cache, + BS5ConstantCache, BS5Cache, + FunctionMapConstantCache, FunctionMapCache } + function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::RK_WITH_SPECIAL_INTERPOLATIONS, idxs, T::Type{Val{D}}, differential_vars) where {D} @@ -18,1682 +20,1517 @@ function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, throw(DerivativeOrderNotPossibleError()) end +function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::RK_WITH_SPECIAL_INTERPOLATIONS, + idxs, T::Type{Val{D}}, differential_vars) where {D} +throw(DerivativeOrderNotPossibleError()) +end + +function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::RK_WITH_SPECIAL_INTERPOLATIONS, + idxs, T::Type{Val{D}}, differential_vars) where {D} +throw(DerivativeOrderNotPossibleError()) +end + #### @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - y₀ + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) +y₀ end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - y₀[idxs] + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) +y₀[idxs] end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - recursivecopy!(out, y₀) + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) +recursivecopy!(out, y₀) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @views out[idxs] .= y₀[idxs] + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) +@views out[idxs] .= y₀[idxs] end -""" -Hairer Norsett Wanner Solving Ordinary Differential Euations I - Nonstiff Problems Page 192 -""" -@def dp5pre0 begin - b10 = Θ - b20 = Θ * (1 - Θ) - b30 = Θ * b20 - b40 = b20^2 +@def owrenzen3unpack begin + if cache isa OrdinaryDiffEqMutableCache + @unpack r13, r12, r23, r22, r33, r32 = cache.tab + else + @unpack r13, r12, r23, r22, r33, r32 = cache + end end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5ConstantCache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 - @inbounds y₀ + dt * (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) +@def owrenzen3pre0 begin + @owrenzen3unpack + Θ² = Θ * Θ + b1Θ = Θ * @evalpoly(Θ, 1, r12, r13) + b2Θ = Θ² * @evalpoly(Θ, r22, r23) + b3Θ = Θ² * @evalpoly(Θ, r32, r33) + b4Θ = Θ² * @evalpoly(Θ, -1, 1) end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5Cache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 @inbounds @.. broadcast=false y₀+dt * - (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) + (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 - @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b10 + k[2][idxs] * b20 + - k[3][idxs] * b30 + k[4][idxs] * b40) + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 + @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 @inbounds @.. broadcast=false out=y₀ + dt * - (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) + (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 @views @.. broadcast=false out=y₀[idxs] + dt * - (k[1][idxs] * b10 + k[2][idxs] * b20 + k[3][idxs] * b30 + - k[4][idxs] * b40) + (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ) out end -@def dp5pre1 begin - b20diff = @evalpoly(Θ, 1, -2) - b30diff = Θ * @evalpoly(Θ, 2, -3) - b40diff = Θ * @evalpoly(Θ, 2, -6, 4) +@def owrenzen3pre1 begin + @owrenzen3unpack + b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13) + b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23) + b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33) + b4Θdiff = Θ * @evalpoly(Θ, -2, 3) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @inbounds @.. broadcast=false k[1]+k[2]*b20diff+k[3]*b30diff+k[4]*b40diff + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen3pre1 + @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @views @.. broadcast=false k[1][idxs]+k[2][idxs]*b20diff+k[3][idxs]*b30diff+ - k[4][idxs]*b40diff -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @inbounds @.. broadcast=false out=k[1] + k[2] * b20diff + k[3] * b30diff + - k[4] * b40diff - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] * b20diff + - k[3][idxs] * b30diff + k[4][idxs] * b40diff - out + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen3pre1 + @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[2][idxs]*b2Θdiff+k[3][idxs]*b3Θdiff+ + k[4][idxs]*b4Θdiff end -@def dp5pre2 begin - b20diff2 = -2 - b30diff2 = @evalpoly(Θ, 2, -6) - b40diff2 = @evalpoly(Θ, 2, -12, 12) +@def owrenzen3pre2 begin + @owrenzen3unpack + b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13) + b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23) + b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33) + b4Θdiff2 = @evalpoly(Θ, -2, 6) invdt = inv(dt) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @inbounds @.. broadcast=false (k[2] * b20diff2 + k[3] * b30diff2 + - k[4] * b40diff2)*invdt + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @inbounds @.. broadcast=false (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2)*invdt end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @views @.. broadcast=false (k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + - k[4][idxs] * b40diff2)*invdt + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2)*invdt end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @inbounds @.. broadcast=false out=(k[2] * b20diff2 + k[3] * b30diff2 + - k[4] * b40diff2) * - invdt + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2) * invdt out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @views @.. broadcast=false out=(k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + - k[4][idxs] * b40diff2) * invdt + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2) * invdt out end -@def dp5pre3 begin - b30diff3 = -6 - b40diff3 = @evalpoly(Θ, -12, 24) +@def owrenzen3pre3 begin + @owrenzen3unpack + b1Θdiff3 = 6 * r13 + b2Θdiff3 = 6 * r23 + b3Θdiff3 = 6 * r33 + b4Θdiff3 = 6 invdt2 = inv(dt)^2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @inbounds @.. broadcast=false (k[3] * b30diff3 + k[4] * b40diff3)*invdt2 + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3)*invdt2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @views @.. broadcast=false (k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3)*invdt2 + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3)*invdt2 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @inbounds @.. broadcast=false out=(k[3] * b30diff3 + k[4] * b40diff3) * invdt2 + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3) * invdt2 out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @views @.. broadcast=false out=(k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3) * invdt2 + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3) * invdt2 out end -@def dp5pre4 begin - b40diff4invdt3 = 24 * inv(dt)^3 +""" +""" + +@def owrenzen4unpack begin + if cache isa OrdinaryDiffEqMutableCache + @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache.tab + else + @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache + end end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @inbounds @.. broadcast=false k[4]*b40diff4invdt3 +@def owrenzen4pre0 begin + @owrenzen4unpack + Θ² = Θ * Θ + b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14) + b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) + b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) + b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) + b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @views @.. broadcast=false k[4][idxs]*b40diff4invdt3 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @inbounds @.. broadcast=false out=k[4] * b40diff4invdt3 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @views @.. broadcast=false out=k[4][idxs] * b40diff4invdt3 - out -end - -""" -Runge–Kutta pairs of order 5(4) satisfying only the first column -simplifying assumption - -Ch. Tsitouras -""" -@def tsit5unpack begin - var"#T#" = constvalue(recursive_unitless_bottom_eltype(y₁)) - r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, r62, r63, r64, r72, r73, r74 = Tsit5Interp(var"#T#") -end - -@def tsit5pre0 begin - @tsit5unpack - Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, r11, r12, r13, r14) - b2Θ = Θ² * @evalpoly(Θ, r22, r23, r24) - b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) - b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) - b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) - b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) - b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - #@.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[2]*b2Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ) - return @inbounds y₀ + - dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + - k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - return @inbounds @.. broadcast=false y₀+dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + - k[4] * b4Θ + - k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen4pre0 + # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ) + return @inbounds y₀ + + dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen4pre0 + # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + + # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ) return y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ) + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 + @owrenzen4pre0 @inbounds @.. broadcast=false out=y₀ + dt * - (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + - k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) - out -end - -@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - @inbounds @simd ivdep for i in eachindex(out) - out[i] = y₀[i] + - dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + - k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) - end + (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ) + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - @views @.. broadcast=false out=y₀[idxs] + - dt * - (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + - k[7][idxs] * b7Θ) + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen4pre0 + @inbounds @.. broadcast=false out=y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + + k[6][idxs] * b6Θ) #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[2][i]*b2Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ) + # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ) #end out end -@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - @inbounds for (j, i) in enumerate(idxs) - out[j] = y₀[i] + - dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + - k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) - end - out -end - -@def tsit5pre1 begin - @tsit5unpack - b1Θdiff = @evalpoly(Θ, r11, 2*r12, 3*r13, 4*r14) - b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23, 4*r24) +@def owrenzen4pre1 begin + @owrenzen4unpack + b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14) b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34) b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44) b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54) b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64) - b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74) end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - # return @.. broadcast=false k[1]*b1Θdiff + k[2]*b2Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff - return @inbounds k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - return @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+ - k[4]*b4Θdiff+k[5]*b5Θdiff+k[6]*b6Θdiff+k[7]*b7Θdiff + @owrenzen4pre1 + @inbounds @.. broadcast=false k[1]*b1Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff+k[5]*b5Θdiff+ + k[6]*b6Θdiff end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - # return @.. broadcast=false k[1][idxs]*b1Θdiff + k[2][idxs]*b2Θdiff + k[3][idxs]*b3Θdiff + k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + k[7][idxs]*b7Θdiff - return k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen4pre1 + @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[3][idxs]*b3Θdiff+k[4][idxs]*b4Θdiff+ + k[5][idxs]*b5Θdiff+k[6][idxs]*b6Θdiff end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + - k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + - k[7] * b7Θdiff - #@inbounds for i in eachindex(out) - # out[i] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff - #end + @owrenzen4pre1 + @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + k[6] * b6Θdiff out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + - k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff - #end + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen4pre1 + @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff out end -@def tsit5pre2 begin - @tsit5unpack +@def owrenzen4pre2 begin + @owrenzen4unpack b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14) - b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23, 12*r24) b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34) b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44) b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54) b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64) - b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74) invdt = inv(dt) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - # return @.. broadcast=false k[1]*b1Θdiff2 + k[2]*b2Θdiff2 + k[3]*b3Θdiff2 + k[4]*b4Θdiff2 + k[5]*b5Θdiff2 + k[6]*b6Θdiff2 + k[7]*b7Θdiff2 - return @inbounds (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2) * invdt + @owrenzen4pre2 + @.. broadcast=false (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2)*invdt end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - # return @.. broadcast=false k[1][idxs]*b1Θdiff2 + k[2][idxs]*b2Θdiff2 + k[3][idxs]*b3Θdiff2 + k[4][idxs]*b4Θdiff2 + k[5][idxs]*b5Θdiff2 + k[6][idxs]*b6Θdiff2 + k[7][idxs]*b7Θdiff2 - return (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + - k[7][idxs] * b7Θdiff2) * invdt + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen4pre2 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2)*invdt end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2 + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + - k[7] * b7Θdiff2) * invdt - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt - #end + @owrenzen4pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2) * invdt out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + - k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + - k[7][idxs] * b7Θdiff2) * invdt - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt - #end + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen4pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2) * invdt out end -@def tsit5pre3 begin - @tsit5unpack +@def owrenzen4pre3 begin + @owrenzen4unpack b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14) - b2Θdiff3 = @evalpoly(Θ, 6*r23, 24*r24) b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34) b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44) b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54) b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64) - b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74) invdt2 = inv(dt)^2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - # return @.. broadcast=false k[1]*b1Θdiff3 + k[2]*b2Θdiff3 + k[3]*b3Θdiff3 + k[4]*b4Θdiff3 + k[5]*b5Θdiff3 + k[6]*b6Θdiff3 + k[7]*b7Θdiff3 - return @inbounds (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3) * invdt2 + @owrenzen4pre3 + @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3)*invdt2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - # return @.. broadcast=false k[1][idxs]*b1Θdiff3 + k[2][idxs]*b2Θdiff3 + k[3][idxs]*b3Θdiff3 + k[4][idxs]*b4Θdiff3 + k[5][idxs]*b5Θdiff3 + k[6][idxs]*b6Θdiff3 + k[7][idxs]*b7Θdiff3 - return (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + - k[7][idxs] * b7Θdiff3) * invdt2 + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen4pre3 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3)*invdt2 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3 + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + - k[7] * b7Θdiff3) * invdt2 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 - #end + @owrenzen4pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3) * invdt2 out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + - k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + - k[7][idxs] * b7Θdiff3) * invdt2 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 - #end + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen4pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3) * invdt2 out end -@def tsit5pre4 begin - @tsit5unpack +@def owrenzen4pre4 begin + @owrenzen4unpack b1Θdiff4 = 24 * r14 - b2Θdiff4 = 24 * r24 b3Θdiff4 = 24 * r34 b4Θdiff4 = 24 * r44 b5Θdiff4 = 24 * r54 b6Θdiff4 = 24 * r64 - b7Θdiff4 = 24 * r74 invdt3 = inv(dt)^3 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - # return @.. broadcast=false k[1]*b1Θdiff4 + k[2]*b2Θdiff4 + k[3]*b3Θdiff4 + k[4]*b4Θdiff4 + k[5]*b5Θdiff4 + k[6]*b6Θdiff4 + k[7]*b7Θdiff4 - return @inbounds (k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + - k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4) * invdt3 + @owrenzen4pre4 + @.. broadcast=false (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4)*invdt3 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - # return @.. broadcast=false k[1][idxs]*b1Θdiff4 + k[2][idxs]*b2Θdiff4 + k[3][idxs]*b3Θdiff4 + k[4][idxs]*b4Θdiff4 + k[5][idxs]*b5Θdiff4 + k[6][idxs]*b6Θdiff4 + k[7][idxs]*b7Θdiff4 - return (k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + - k[7][idxs] * b7Θdiff4) * invdt3 + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen4pre4 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4)*invdt3 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + - k[4] * b4Θdiff4 + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + - k[7] * b7Θdiff4) * invdt3 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 - #end + @owrenzen4pre4 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4) * invdt3 out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + - k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + - k[7][idxs] * b7Θdiff4) * invdt3 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 - #end + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen4pre4 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4) * invdt3 out end -""" -""" -@def owrenzen3unpack begin +@def owrenzen5unpack begin if cache isa OrdinaryDiffEqMutableCache - @unpack r13, r12, r23, r22, r33, r32 = cache.tab + @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache.tab else - @unpack r13, r12, r23, r22, r33, r32 = cache + @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache end end -@def owrenzen3pre0 begin - @owrenzen3unpack +@def owrenzen5pre0 begin + @owrenzen5unpack Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, 1, r12, r13) - b2Θ = Θ² * @evalpoly(Θ, r22, r23) - b3Θ = Θ² * @evalpoly(Θ, r32, r33) - b4Θ = Θ² * @evalpoly(Θ, -1, 1) + b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14, r15) + b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34, r35) + b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44, r45) + b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54, r55) + b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64, r65) + b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74, r75) + b8Θ = Θ² * @evalpoly(Θ, r82, r83, r84, r85) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 - @inbounds @.. broadcast=false y₀+dt * - (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) + @owrenzen5pre0 + # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + + # k[7]*b7Θ + k[8]*b8Θ) + return @inbounds y₀ + + dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ + + k[7] * b7Θ + k[8] * b8Θ) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 - @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + - k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ) + @owrenzen5pre0 + # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + + # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + + # k[7][idxs]*b7Θ + k[8][idxs]*b8Θ) + return y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + + k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 + @owrenzen5pre0 @inbounds @.. broadcast=false out=y₀ + dt * - (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) + (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ + + k[7] * b7Θ + k[8] * b8Θ) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 + @owrenzen5pre0 @views @.. broadcast=false out=y₀[idxs] + - dt * - (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ) + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + + k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) + #end out end -@def owrenzen3pre1 begin - @owrenzen3unpack - b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13) - b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23) - b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33) - b4Θdiff = Θ * @evalpoly(Θ, -2, 3) +@def owrenzen5pre1 begin + @owrenzen5unpack + b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14, 5*r15) + b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34, 5*r35) + b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44, 5*r45) + b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54, 5*r55) + b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64, 5*r65) + b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74, 5*r75) + b8Θdiff = Θ * @evalpoly(Θ, 2*r82, 3*r83, 4*r84, 5*r85) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen3pre1 - @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff + @owrenzen5pre1 + return @inbounds k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + k[5] * b5Θdiff + + k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen3pre1 - @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[2][idxs]*b2Θdiff+k[3][idxs]*b3Θdiff+ - k[4][idxs]*b4Θdiff + @owrenzen5pre1 + k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + + k[6][idxs] * b6Θdiff + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen3pre1 - @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + - k[4] * b4Θdiff + @owrenzen5pre1 + @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff + + k[8] * b8Θdiff + #@inbounds for i in eachindex(out) + # out[i] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + + # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen3pre1 - @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + - k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + @owrenzen5pre1 + @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + + # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + #end out end -@def owrenzen3pre2 begin - @owrenzen3unpack - b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13) - b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23) - b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33) - b4Θdiff2 = @evalpoly(Θ, -2, 6) +@def owrenzen5pre2 begin + @owrenzen5unpack + b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14, 20*r15) + b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34, 20*r35) + b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44, 20*r45) + b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54, 20*r55) + b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64, 20*r65) + b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74, 20*r75) + b8Θdiff2 = @evalpoly(Θ, 2*r82, 6*r83, 12*r84, 20*r85) invdt = inv(dt) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @inbounds @.. broadcast=false (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2)*invdt + @owrenzen5pre2 + return @inbounds (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + + k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + k[8] * b8Θdiff2) * invdt end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + - k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2)*invdt -end + @owrenzen5pre2 + (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + + k[6][idxs] * b6Θdiff2 + k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt +end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2) * invdt + @owrenzen5pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + + k[8] * b8Θdiff2) * invdt + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + + # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + - k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2) * invdt + @owrenzen5pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + + k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + + # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt + #end out end -@def owrenzen3pre3 begin - @owrenzen3unpack - b1Θdiff3 = 6 * r13 - b2Θdiff3 = 6 * r23 - b3Θdiff3 = 6 * r33 - b4Θdiff3 = 6 +@def owrenzen5pre3 begin + @owrenzen5unpack + b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14, 60*r15) + b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34, 60*r35) + b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44, 60*r45) + b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54, 60*r55) + b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64, 60*r65) + b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74, 60*r75) + b8Θdiff3 = @evalpoly(Θ, 6*r83, 24*r84, 60*r85) invdt2 = inv(dt)^2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3)*invdt2 + @owrenzen5pre3 + return @inbounds (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + + k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + k[8] * b8Θdiff3) * invdt2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + - k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3)*invdt2 + @owrenzen5pre3 + (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + + k[6][idxs] * b6Θdiff3 + k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3) * invdt2 + @owrenzen5pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + + k[8] * b8Θdiff3) * invdt2 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + + # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + - k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3) * invdt2 + @owrenzen5pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + + k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + + # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 + #end out end -""" -""" -@def owrenzen4unpack begin - if cache isa OrdinaryDiffEqMutableCache - @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache.tab - else - @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache - end -end - -@def owrenzen4pre0 begin - @owrenzen4unpack - Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14) - b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) - b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) - b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) - b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) +@def owrenzen5pre4 begin + @owrenzen5unpack + b1Θdiff4 = @evalpoly(Θ, 24*r14, 120*r15) + b3Θdiff4 = @evalpoly(Θ, 24*r34, 120*r35) + b4Θdiff4 = @evalpoly(Θ, 24*r44, 120*r45) + b5Θdiff4 = @evalpoly(Θ, 24*r54, 120*r55) + b6Θdiff4 = @evalpoly(Θ, 24*r64, 120*r65) + b7Θdiff4 = @evalpoly(Θ, 24*r74, 120*r75) + b8Θdiff4 = @evalpoly(Θ, 24*r84, 120*r85) + invdt3 = inv(dt)^3 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ) - return @inbounds y₀ + - dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ) + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + return @inbounds (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + + k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + k[8] * b8Θdiff4) * invdt3 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + - # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ) - return y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ) + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + + k[6][idxs] * b6Θdiff4 + k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - @inbounds @.. broadcast=false out=y₀ + - dt * - (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ) + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + + k[8] * b8Θdiff4) * invdt3 #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ) + # out[i] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + + # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - @inbounds @.. broadcast=false out=y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + - k[6][idxs] * b6Θ) + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + + k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ) + # out[j] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + + # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 #end out end -@def owrenzen4pre1 begin - @owrenzen4unpack - b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14) - b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34) - b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44) - b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54) - b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64) +@def owrenzen5pre5 begin + @owrenzen5unpack + b1Θdiff5 = 120 * r15 + b3Θdiff5 = 120 * r35 + b4Θdiff5 = 120 * r45 + b5Θdiff5 = 120 * r55 + b6Θdiff5 = 120 * r65 + b7Θdiff5 = 120 * r75 + b8Θdiff5 = 120 * r85 + invdt4 = inv(dt)^4 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @inbounds @.. broadcast=false k[1]*b1Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff+k[5]*b5Θdiff+ - k[6]*b6Θdiff + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + return @inbounds (k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + + k[5] * b5Θdiff5 + + k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + k[8] * b8Θdiff5) * invdt4 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[3][idxs]*b3Θdiff+k[4][idxs]*b4Θdiff+ - k[5][idxs]*b5Θdiff+k[6][idxs]*b6Θdiff + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + (k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + k[4][idxs] * b4Θdiff5 + + k[5][idxs] * b5Θdiff5 + + k[6][idxs] * b6Θdiff5 + k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + k[6] * b6Θdiff + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + + k[5] * b5Θdiff5 + k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + + k[8] * b8Θdiff5) * invdt4 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + + # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + + k[4][idxs] * b4Θdiff5 + + k[5][idxs] * b5Θdiff5 + k[6][idxs] * b6Θdiff5 + + k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + + # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 + #end out end -@def owrenzen4pre2 begin - @owrenzen4unpack - b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14) - b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34) - b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44) - b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54) - b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64) - invdt = inv(dt) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @.. broadcast=false (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2)*invdt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2)*invdt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2) * invdt - out +@def bs5unpack begin + if cache isa OrdinaryDiffEqMutableCache + @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache.tab + else + @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache + end end -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2) * invdt - out +@def bs5pre0 begin + @bs5unpack + Θ² = Θ * Θ + b1Θ = Θ² * @evalpoly(Θ, r012, r013, r014, r015, r016) + b3Θ = Θ² * @evalpoly(Θ, r032, r033, r034, r035, r036) + b4Θ = Θ² * @evalpoly(Θ, r042, r043, r044, r045, r046) + b5Θ = Θ² * @evalpoly(Θ, r052, r053, r054, r055, r056) + b6Θ = Θ² * @evalpoly(Θ, r062, r063, r064, r065, r066) + b7Θ = Θ² * @evalpoly(Θ, r072, r073, r074, r075, r076) + b8Θ = Θ² * @evalpoly(Θ, r082, r083, r084, r085, r086) + b9Θ = (Θ² * Θ) * @evalpoly(Θ, r093, r094, r095, + r096) + b10Θ = Θ² * @evalpoly(Θ, r102, r103, r104, r105, r106) + b11Θ = Θ² * @evalpoly(Θ, r112, r113, r114, r115, r116) end -@def owrenzen4pre3 begin - @owrenzen4unpack - b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14) - b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34) - b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44) - b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54) - b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64) - invdt2 = inv(dt)^2 +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5ConstantCache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) + return @inbounds y₀ + dt * Θ * k[1] + + dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + k[10] * b10Θ + + k[11] * b11Θ) end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3)*invdt2 +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5Cache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) + return @inbounds @.. broadcast=false y₀+dt*Θ*k[1]+ + dt*(k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + + k[5] * b5Θ + + k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + + k[9] * b9Θ + k[10] * b10Θ + k[11] * b11Θ) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3)*invdt2 + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + # return @.. broadcast=false y₀[idxs] + dt*Θ*k[1][idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + + # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + k[7][idxs]*b7Θ + + # k[8][idxs]*b8Θ + k[9][idxs]*b9Θ + k[10][idxs]*b10Θ + k[11][idxs]*b11Θ) + return y₀[idxs] + dt * Θ * k[1][idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + + k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3) * invdt2 + cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + @inbounds @.. broadcast=false out=y₀ + dt * Θ * k[1] + + dt * + (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + + k[10] * b10Θ + k[11] * b11Θ) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3) * invdt2 + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + @views @.. broadcast=false out=y₀[idxs] + dt * Θ * k[1][idxs] + + dt * + (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + k[4][idxs] * b4Θ + + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + + k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + + k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) + #end out end -@def owrenzen4pre4 begin - @owrenzen4unpack - b1Θdiff4 = 24 * r14 - b3Θdiff4 = 24 * r34 - b4Θdiff4 = 24 * r44 - b5Θdiff4 = 24 * r54 - b6Θdiff4 = 24 * r64 - invdt3 = inv(dt)^3 +@def bs5pre1 begin + @bs5unpack + Θ² = Θ * Θ + b1Θdiff = Θ * @evalpoly(Θ, 2*r012, 3*r013, 4*r014, 5*r015, 6*r016) + b3Θdiff = Θ * @evalpoly(Θ, 2*r032, 3*r033, 4*r034, 5*r035, 6*r036) + b4Θdiff = Θ * @evalpoly(Θ, 2*r042, 3*r043, 4*r044, 5*r045, 6*r046) + b5Θdiff = Θ * @evalpoly(Θ, 2*r052, 3*r053, 4*r054, 5*r055, 6*r056) + b6Θdiff = Θ * @evalpoly(Θ, 2*r062, 3*r063, 4*r064, 5*r065, 6*r066) + b7Θdiff = Θ * @evalpoly(Θ, 2*r072, 3*r073, 4*r074, 5*r075, 6*r076) + b8Θdiff = Θ * @evalpoly(Θ, 2*r082, 3*r083, 4*r084, 5*r085, 6*r086) + b9Θdiff = Θ² * @evalpoly(Θ, 3*r093, 4*r094, 5*r095, 6*r096) + b10Θdiff = Θ * @evalpoly(Θ, 2*r102, 3*r103, 4*r104, 5*r105, 6*r106) + b11Θdiff = Θ * @evalpoly(Θ, 2*r112, 3*r113, 4*r114, 5*r115, 6*r116) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @.. broadcast=false (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4)*invdt3 + cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + # return @.. broadcast=false k[1] + k[1]*b1Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff + k[8]*b8Θdiff + k[9]*b9Θdiff + k[10]*b10Θdiff + k[11]*b11Θdiff + return @inbounds k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + + k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + + k[10] * b10Θdiff + k[11] * b11Θdiff end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4)*invdt3 + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + # return @.. broadcast=false k[1][idxs] + k[1][idxs]*b1Θdiff + k[3][idxs]*b3Θdiff + + # k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + + # k[7][idxs]*b7Θdiff + k[8][idxs]*b8Θdiff + k[9][idxs]*b9Θdiff + + # k[10][idxs]*b10Θdiff + k[11][idxs]*b11Θdiff + return @inbounds k[1][idxs] + k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + k[9][idxs] * b9Θdiff + + k[10][idxs] * b10Θdiff + k[11][idxs] * b11Θdiff end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4) * invdt3 + cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + @inbounds @.. broadcast=false out=k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + + k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + + k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + + k[10] * b10Θdiff + k[11] * b11Θdiff + #@inbounds for i in eachindex(out) + # out[i] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4) * invdt3 + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + @views @.. broadcast=false out=k[1][idxs] + k[1][idxs] * b1Θdiff + + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + + k[9][idxs] * b9Θdiff + k[10][idxs] * b10Θdiff + + k[11][idxs] * b11Θdiff + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff + #end out end -""" -""" -@def owrenzen5unpack begin - if cache isa OrdinaryDiffEqMutableCache - @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache.tab - else - @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache - end +@def dp5pre0 begin + b10 = Θ + b20 = Θ * (1 - Θ) + b30 = Θ * b20 + b40 = b20^2 end -@def owrenzen5pre0 begin - @owrenzen5unpack - Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14, r15) - b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34, r35) - b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44, r45) - b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54, r55) - b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64, r65) - b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74, r75) - b8Θ = Θ² * @evalpoly(Θ, r82, r83, r84, r85) +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5ConstantCache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @inbounds y₀ + dt * (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 - # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + - # k[7]*b7Θ + k[8]*b8Θ) - return @inbounds y₀ + - dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ + - k[7] * b7Θ + k[8] * b8Θ) +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5Cache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @inbounds @.. broadcast=false y₀+dt * + (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 - # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + - # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + - # k[7][idxs]*b7Θ + k[8][idxs]*b8Θ) - return y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + - k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b10 + k[2][idxs] * b20 + + k[3][idxs] * b30 + k[4][idxs] * b40) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 @inbounds @.. broadcast=false out=y₀ + dt * - (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ + - k[7] * b7Θ + k[8] * b8Θ) - #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) - #end + (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 @views @.. broadcast=false out=y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + - k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) - #end + dt * + (k[1][idxs] * b10 + k[2][idxs] * b20 + k[3][idxs] * b30 + + k[4][idxs] * b40) out end -@def owrenzen5pre1 begin - @owrenzen5unpack - b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14, 5*r15) - b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34, 5*r35) - b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44, 5*r45) - b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54, 5*r55) - b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64, 5*r65) - b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74, 5*r75) - b8Θdiff = Θ * @evalpoly(Θ, 2*r82, 3*r83, 4*r84, 5*r85) +@def dp5pre1 begin + b20diff = @evalpoly(Θ, 1, -2) + b30diff = Θ * @evalpoly(Θ, 2, -3) + b40diff = Θ * @evalpoly(Θ, 2, -6, 4) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - return @inbounds k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + k[5] * b5Θdiff + - k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @inbounds @.. broadcast=false k[1]+k[2]*b20diff+k[3]*b30diff+k[4]*b40diff end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + - k[6][idxs] * b6Θdiff + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @views @.. broadcast=false k[1][idxs]+k[2][idxs]*b20diff+k[3][idxs]*b30diff+ + k[4][idxs]*b40diff end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff + - k[8] * b8Θdiff - #@inbounds for i in eachindex(out) - # out[i] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + - # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @inbounds @.. broadcast=false out=k[1] + k[2] * b20diff + k[3] * b30diff + + k[4] * b40diff out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + - # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] * b20diff + + k[3][idxs] * b30diff + k[4][idxs] * b40diff out end -@def owrenzen5pre2 begin - @owrenzen5unpack - b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14, 20*r15) - b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34, 20*r35) - b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44, 20*r45) - b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54, 20*r55) - b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64, 20*r65) - b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74, 20*r75) - b8Θdiff2 = @evalpoly(Θ, 2*r82, 6*r83, 12*r84, 20*r85) +@def dp5pre2 begin + b20diff2 = -2 + b30diff2 = @evalpoly(Θ, 2, -6) + b40diff2 = @evalpoly(Θ, 2, -12, 12) invdt = inv(dt) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - return @inbounds (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + - k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + k[8] * b8Θdiff2) * invdt + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @inbounds @.. broadcast=false (k[2] * b20diff2 + k[3] * b30diff2 + + k[4] * b40diff2)*invdt end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + - k[6][idxs] * b6Θdiff2 + k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @views @.. broadcast=false (k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + + k[4][idxs] * b40diff2)*invdt end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + - k[8] * b8Θdiff2) * invdt - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + - # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @inbounds @.. broadcast=false out=(k[2] * b20diff2 + k[3] * b30diff2 + + k[4] * b40diff2) * + invdt out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + - k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + - # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @views @.. broadcast=false out=(k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + + k[4][idxs] * b40diff2) * invdt out end -@def owrenzen5pre3 begin - @owrenzen5unpack - b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14, 60*r15) - b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34, 60*r35) - b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44, 60*r45) - b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54, 60*r55) - b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64, 60*r65) - b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74, 60*r75) - b8Θdiff3 = @evalpoly(Θ, 6*r83, 24*r84, 60*r85) +@def dp5pre3 begin + b30diff3 = -6 + b40diff3 = @evalpoly(Θ, -12, 24) invdt2 = inv(dt)^2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - return @inbounds (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + - k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + k[8] * b8Θdiff3) * invdt2 + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @inbounds @.. broadcast=false (k[3] * b30diff3 + k[4] * b40diff3)*invdt2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + - k[6][idxs] * b6Θdiff3 + k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @views @.. broadcast=false (k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3)*invdt2 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + - k[8] * b8Θdiff3) * invdt2 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + - # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @inbounds @.. broadcast=false out=(k[3] * b30diff3 + k[4] * b40diff3) * invdt2 out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + - k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + - # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @views @.. broadcast=false out=(k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3) * invdt2 out end -@def owrenzen5pre4 begin - @owrenzen5unpack - b1Θdiff4 = @evalpoly(Θ, 24*r14, 120*r15) - b3Θdiff4 = @evalpoly(Θ, 24*r34, 120*r35) - b4Θdiff4 = @evalpoly(Θ, 24*r44, 120*r45) - b5Θdiff4 = @evalpoly(Θ, 24*r54, 120*r55) - b6Θdiff4 = @evalpoly(Θ, 24*r64, 120*r65) - b7Θdiff4 = @evalpoly(Θ, 24*r74, 120*r75) - b8Θdiff4 = @evalpoly(Θ, 24*r84, 120*r85) - invdt3 = inv(dt)^3 +@def dp5pre4 begin + b40diff4invdt3 = 24 * inv(dt)^3 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - return @inbounds (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + - k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + k[8] * b8Θdiff4) * invdt3 + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @inbounds @.. broadcast=false k[4]*b40diff4invdt3 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + - k[6][idxs] * b6Θdiff4 + k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @views @.. broadcast=false k[4][idxs]*b40diff4invdt3 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + - k[8] * b8Θdiff4) * invdt3 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + - # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @inbounds @.. broadcast=false out=k[4] * b40diff4invdt3 out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + - k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + - # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 - #end + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @views @.. broadcast=false out=k[4][idxs] * b40diff4invdt3 out end -@def owrenzen5pre5 begin - @owrenzen5unpack - b1Θdiff5 = 120 * r15 - b3Θdiff5 = 120 * r35 - b4Θdiff5 = 120 * r45 - b5Θdiff5 = 120 * r55 - b6Θdiff5 = 120 * r65 - b7Θdiff5 = 120 * r75 - b8Θdiff5 = 120 * r85 - invdt4 = inv(dt)^4 +@def tsit5unpack begin + var"#T#" = constvalue(recursive_unitless_bottom_eltype(y₁)) + r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, r62, r63, r64, r72, r73, r74 = Tsit5Interp(var"#T#") end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - return @inbounds (k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + - k[5] * b5Θdiff5 + - k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + k[8] * b8Θdiff5) * invdt4 +@def tsit5pre0 begin + @tsit5unpack + Θ² = Θ * Θ + b1Θ = Θ * @evalpoly(Θ, r11, r12, r13, r14) + b2Θ = Θ² * @evalpoly(Θ, r22, r23, r24) + b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) + b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) + b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) + b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) + b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + #@.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[2]*b2Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ) + return @inbounds y₀ + + dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + + k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + return @inbounds @.. broadcast=false y₀+dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + + k[4] * b4Θ + + k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - (k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + k[4][idxs] * b4Θdiff5 + - k[5][idxs] * b5Θdiff5 + - k[6][idxs] * b6Θdiff5 + k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + return y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + - k[5] * b5Θdiff5 + k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + - k[8] * b8Θdiff5) * invdt4 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + - # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 - #end + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @inbounds @.. broadcast=false out=y₀ + + dt * + (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + + k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) + out +end + +@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @inbounds @simd ivdep for i in eachindex(out) + out[i] = y₀[i] + + dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + + k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) + end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + - k[4][idxs] * b4Θdiff5 + - k[5][idxs] * b5Θdiff5 + k[6][idxs] * b6Θdiff5 + - k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @views @.. broadcast=false out=y₀[idxs] + + dt * + (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + + k[7][idxs] * b7Θ) #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + - # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 + # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[2][i]*b2Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ) #end out end -""" -Coefficients taken from RKSuite -""" -@def bs5unpack begin - if cache isa OrdinaryDiffEqMutableCache - @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache.tab - else - @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache +@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @inbounds for (j, i) in enumerate(idxs) + out[j] = y₀[i] + + dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + + k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) end + out end -@def bs5pre0 begin - @bs5unpack - Θ² = Θ * Θ - b1Θ = Θ² * @evalpoly(Θ, r012, r013, r014, r015, r016) - b3Θ = Θ² * @evalpoly(Θ, r032, r033, r034, r035, r036) - b4Θ = Θ² * @evalpoly(Θ, r042, r043, r044, r045, r046) - b5Θ = Θ² * @evalpoly(Θ, r052, r053, r054, r055, r056) - b6Θ = Θ² * @evalpoly(Θ, r062, r063, r064, r065, r066) - b7Θ = Θ² * @evalpoly(Θ, r072, r073, r074, r075, r076) - b8Θ = Θ² * @evalpoly(Θ, r082, r083, r084, r085, r086) - b9Θ = (Θ² * Θ) * @evalpoly(Θ, r093, r094, r095, - r096) - b10Θ = Θ² * @evalpoly(Θ, r102, r103, r104, r105, r106) - b11Θ = Θ² * @evalpoly(Θ, r112, r113, r114, r115, r116) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5ConstantCache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) - return @inbounds y₀ + dt * Θ * k[1] + - dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + k[10] * b10Θ + - k[11] * b11Θ) +@def tsit5pre1 begin + @tsit5unpack + b1Θdiff = @evalpoly(Θ, r11, 2*r12, 3*r13, 4*r14) + b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23, 4*r24) + b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34) + b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44) + b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54) + b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64) + b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74) end -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5Cache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) - return @inbounds @.. broadcast=false y₀+dt*Θ*k[1]+ - dt*(k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + - k[5] * b5Θ + - k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + - k[9] * b9Θ + k[10] * b10Θ + k[11] * b11Θ) +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + # return @.. broadcast=false k[1]*b1Θdiff + k[2]*b2Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff + return @inbounds k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + return @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+ + k[4]*b4Θdiff+k[5]*b5Θdiff+k[6]*b6Θdiff+k[7]*b7Θdiff end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - # return @.. broadcast=false y₀[idxs] + dt*Θ*k[1][idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + - # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + k[7][idxs]*b7Θ + - # k[8][idxs]*b8Θ + k[9][idxs]*b9Θ + k[10][idxs]*b10Θ + k[11][idxs]*b11Θ) - return y₀[idxs] + dt * Θ * k[1][idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + - k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + # return @.. broadcast=false k[1][idxs]*b1Θdiff + k[2][idxs]*b2Θdiff + k[3][idxs]*b3Θdiff + k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + k[7][idxs]*b7Θdiff + return k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - @inbounds @.. broadcast=false out=y₀ + dt * Θ * k[1] + - dt * - (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + - k[10] * b10Θ + k[11] * b11Θ) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + + k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + + k[7] * b7Θdiff #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) + # out[i] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - @views @.. broadcast=false out=y₀[idxs] + dt * Θ * k[1][idxs] + - dt * - (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + k[4][idxs] * b4Θ + - k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + - k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + - k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) + # out[j] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff #end out end -@def bs5pre1 begin - @bs5unpack - Θ² = Θ * Θ - b1Θdiff = Θ * @evalpoly(Θ, 2*r012, 3*r013, 4*r014, 5*r015, 6*r016) - b3Θdiff = Θ * @evalpoly(Θ, 2*r032, 3*r033, 4*r034, 5*r035, 6*r036) - b4Θdiff = Θ * @evalpoly(Θ, 2*r042, 3*r043, 4*r044, 5*r045, 6*r046) - b5Θdiff = Θ * @evalpoly(Θ, 2*r052, 3*r053, 4*r054, 5*r055, 6*r056) - b6Θdiff = Θ * @evalpoly(Θ, 2*r062, 3*r063, 4*r064, 5*r065, 6*r066) - b7Θdiff = Θ * @evalpoly(Θ, 2*r072, 3*r073, 4*r074, 5*r075, 6*r076) - b8Θdiff = Θ * @evalpoly(Θ, 2*r082, 3*r083, 4*r084, 5*r085, 6*r086) - b9Θdiff = Θ² * @evalpoly(Θ, 3*r093, 4*r094, 5*r095, 6*r096) - b10Θdiff = Θ * @evalpoly(Θ, 2*r102, 3*r103, 4*r104, 5*r105, 6*r106) - b11Θdiff = Θ * @evalpoly(Θ, 2*r112, 3*r113, 4*r114, 5*r115, 6*r116) +@def tsit5pre2 begin + @tsit5unpack + b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14) + b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23, 12*r24) + b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34) + b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44) + b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54) + b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64) + b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74) + invdt = inv(dt) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - # return @.. broadcast=false k[1] + k[1]*b1Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff + k[8]*b8Θdiff + k[9]*b9Θdiff + k[10]*b10Θdiff + k[11]*b11Θdiff - return @inbounds k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + - k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + - k[10] * b10Θdiff + k[11] * b11Θdiff + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + # return @.. broadcast=false k[1]*b1Θdiff2 + k[2]*b2Θdiff2 + k[3]*b3Θdiff2 + k[4]*b4Θdiff2 + k[5]*b5Θdiff2 + k[6]*b6Θdiff2 + k[7]*b7Θdiff2 + return @inbounds (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2) * invdt end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - # return @.. broadcast=false k[1][idxs] + k[1][idxs]*b1Θdiff + k[3][idxs]*b3Θdiff + - # k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + - # k[7][idxs]*b7Θdiff + k[8][idxs]*b8Θdiff + k[9][idxs]*b9Θdiff + - # k[10][idxs]*b10Θdiff + k[11][idxs]*b11Θdiff - return @inbounds k[1][idxs] + k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + k[9][idxs] * b9Θdiff + - k[10][idxs] * b10Θdiff + k[11][idxs] * b11Θdiff + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + # return @.. broadcast=false k[1][idxs]*b1Θdiff2 + k[2][idxs]*b2Θdiff2 + k[3][idxs]*b3Θdiff2 + k[4][idxs]*b4Θdiff2 + k[5][idxs]*b5Θdiff2 + k[6][idxs]*b6Θdiff2 + k[7][idxs]*b7Θdiff2 + return (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + + k[7][idxs] * b7Θdiff2) * invdt end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - @inbounds @.. broadcast=false out=k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + - k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + - k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + - k[10] * b10Θdiff + k[11] * b11Θdiff + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2 + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + + k[7] * b7Θdiff2) * invdt #@inbounds for i in eachindex(out) - # out[i] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff + # out[i] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - @views @.. broadcast=false out=k[1][idxs] + k[1][idxs] * b1Θdiff + - k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + - k[9][idxs] * b9Θdiff + k[10][idxs] * b10Θdiff + - k[11][idxs] * b11Θdiff + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + + k[7][idxs] * b7Θdiff2) * invdt #@inbounds for (j,i) in enumerate(idxs) - # out[j] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff + # out[j] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt #end out end -""" -""" +@def tsit5pre3 begin + @tsit5unpack + b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14) + b2Θdiff3 = @evalpoly(Θ, 6*r23, 24*r24) + b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34) + b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44) + b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54) + b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64) + b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74) + invdt2 = inv(dt)^2 +end + @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - Θ1 = 1 - Θ - # return @.. broadcast=false y₀ + dt*Θ*(k[1] + Θ1*(k[2] + Θ*(k[3]+Θ1*(k[4] + Θ*(k[5] + Θ1*(k[6]+Θ*k[7])))))) - return @inbounds y₀ + - dt * Θ * - (k[1] + - Θ1 * (k[2] + - Θ * (k[3] + Θ1 * (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + # return @.. broadcast=false k[1]*b1Θdiff3 + k[2]*b2Θdiff3 + k[3]*b3Θdiff3 + k[4]*b4Θdiff3 + k[5]*b5Θdiff3 + k[6]*b6Θdiff3 + k[7]*b7Θdiff3 + return @inbounds (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3) * invdt2 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - Θ1 = 1 - Θ - # return @.. broadcast=false y₀[idxs] + dt*Θ*(k[1][idxs] + Θ1*(k[2][idxs] + Θ*(k[3][idxs]+Θ1*(k[4][idxs] + Θ*(k[5][idxs] + Θ1*(k[6][idxs]+Θ*k[7][idxs])))))) - return y₀[idxs] + - dt * Θ * - (k[1][idxs] + - Θ1 * (k[2][idxs] + - Θ * (k[3][idxs] + - Θ1 * (k[4][idxs] + Θ * (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + # return @.. broadcast=false k[1][idxs]*b1Θdiff3 + k[2][idxs]*b2Θdiff3 + k[3][idxs]*b3Θdiff3 + k[4][idxs]*b4Θdiff3 + k[5][idxs]*b5Θdiff3 + k[6][idxs]*b6Θdiff3 + k[7][idxs]*b7Θdiff3 + return (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + + k[7][idxs] * b7Θdiff3) * invdt2 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - Θ1 = 1 - Θ - @inbounds @.. broadcast=false out=y₀ + - dt * Θ * - (k[1] + - Θ1 * (k[2] + - Θ * (k[3] + - Θ1 * - (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3 + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + + k[7] * b7Θdiff3) * invdt2 #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) + # out[i] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - Θ1 = 1 - Θ - @views @.. broadcast=false out=y₀[idxs] + - dt * Θ * - (k[1][idxs] + - Θ1 * (k[2][idxs] + - Θ * (k[3][idxs] + - Θ1 * (k[4][idxs] + - Θ * - (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + + k[7][idxs] * b7Θdiff3) * invdt2 #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) + # out[j] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 #end out end +@def tsit5pre4 begin + @tsit5unpack + b1Θdiff4 = 24 * r14 + b2Θdiff4 = 24 * r24 + b3Θdiff4 = 24 * r34 + b4Θdiff4 = 24 * r44 + b5Θdiff4 = 24 * r54 + b6Θdiff4 = 24 * r64 + b7Θdiff4 = 24 * r74 + invdt3 = inv(dt)^3 +end + @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @inbounds b1diff = @.. broadcast=false k[1]+k[2] - @inbounds b2diff = @.. broadcast=false -2*k[2]+2*k[3]+2*k[4] - @inbounds b3diff = @.. broadcast=false -3 * k[3]-6 * k[4]+3*k[5]+3*k[6] - @inbounds b4diff = @.. broadcast=false 4 * k[4] - 8 * k[5] - 12 * k[6]+4 * k[7] - @inbounds b5diff = @.. broadcast=false 5 * k[5] + 15 * k[6]-15 * k[7] - @inbounds b6diff = @.. broadcast=false -6 * k[6]+18 * k[7] - @inbounds b7diff = @.. broadcast=false -7*k[7] - # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) - return b1diff + - Θ * - (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + # return @.. broadcast=false k[1]*b1Θdiff4 + k[2]*b2Θdiff4 + k[3]*b3Θdiff4 + k[4]*b4Θdiff4 + k[5]*b5Θdiff4 + k[6]*b6Θdiff4 + k[7]*b7Θdiff4 + return @inbounds (k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4) * invdt3 end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - b1diff = @.. broadcast=false k[1][idxs]+k[2][idxs] - b2diff = @.. broadcast=false -2*k[2][idxs]+2*k[3][idxs]+2*k[4][idxs] - b3diff = @.. broadcast=false -3 * k[3][idxs]-6 * k[4][idxs]+3*k[5][idxs]+3*k[6][idxs] - b4diff = @.. broadcast=false 4 * k[4][idxs] - 8 * k[5][idxs] - - 12 * k[6][idxs]+4 * k[7][idxs] - b5diff = @.. broadcast=false 5 * k[5][idxs] + 15 * k[6][idxs]-15 * k[7][idxs] - b6diff = @.. broadcast=false -6 * k[6][idxs]+18 * k[7][idxs] - b7diff = @.. broadcast=false -7*k[7][idxs] - # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) - return b1diff + - Θ * - (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + # return @.. broadcast=false k[1][idxs]*b1Θdiff4 + k[2][idxs]*b2Θdiff4 + k[3][idxs]*b3Θdiff4 + k[4][idxs]*b4Θdiff4 + k[5][idxs]*b5Θdiff4 + k[6][idxs]*b6Θdiff4 + k[7][idxs]*b7Θdiff4 + return (k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + + k[7][idxs] * b7Θdiff4) * invdt3 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - # b1diff = k[1] + k[2] - # b2diff = -2*k[2] + 2*k[3] + 2*k[4] - # b3diff = -3*k[3] - 6*k[4] + 3*k[5] + 3*k[6] - # b4diff = 4*k[4] - 8*k[5] - 12*k[6] + 4*k[7] - # b5diff = 5*k[5] + 15*k[6] - 15*k[7] - # b6diff = -6*k[6] + 18*k[7] - # @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + - # Θ*(b5diff + Θ*(b6diff - 7*k[7]*Θ))))) - @views @.. broadcast=false out=k[1] + k[2] + - Θ * (-2 * k[2] + 2 * k[3] + 2 * k[4] + - Θ * (-3 * k[3] - 6 * k[4] + 3 * k[5] + 3 * k[6] + - Θ * (4 * k[4] - 8 * k[5] - 12 * k[6] + 4 * k[7] + - Θ * (5 * k[5] + 15 * k[6] - 15 * k[7] + - Θ * (-6 * k[6] + 18 * k[7] - 7 * k[7] * Θ))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + + k[4] * b4Θdiff4 + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + + k[7] * b7Θdiff4) * invdt3 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 + #end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - # b1diff = k[1][idxs] + k[2][idxs] - # b2diff = -2*k[2][idxs] + 2*k[3][idxs] + 2*k[4][idxs] - # b3diff = -3*k[3][idxs] - 6*k[4][idxs] + 3*k[5][idxs] + 3*k[6][idxs] - # b4diff = 4*k[4][idxs] - 8*k[5][idxs] - 12*k[6][idxs] + 4*k[7][idxs] - # b5diff = 5*k[5][idxs] + 15*k[6][idxs] - 15*k[7][idxs] - # b6diff = -6*k[6][idxs] + 18*k[7][idxs] - #@views @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + - # Θ*(b5diff + Θ*(b6diff - 7*k[7][idxs]*Θ))))) - @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] + - Θ * (-2 * k[2][idxs] + 2 * k[3][idxs] + 2 * k[4][idxs] + - Θ * - (-3 * k[3][idxs] - 6 * k[4][idxs] + 3 * k[5][idxs] + - 3 * k[6][idxs] + - Θ * - (4 * k[4][idxs] - 8 * k[5][idxs] - 12 * k[6][idxs] + - 4 * k[7][idxs] + - Θ * - (5 * k[5][idxs] + 15 * k[6][idxs] - 15 * k[7][idxs] + - Θ * (-6 * k[6][idxs] + 18 * k[7][idxs] - - 7 * k[7][idxs] * Θ))))) + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + + k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + + k[7][idxs] * b7Θdiff4) * invdt3 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 + #end out -end - -""" -""" +end \ No newline at end of file diff --git a/src/dense/low_order_rk_addsteps.jl b/lib/OrdinaryLowOrderRK/src/low_order_rk_addsteps.jl similarity index 100% rename from src/dense/low_order_rk_addsteps.jl rename to lib/OrdinaryLowOrderRK/src/low_order_rk_addsteps.jl diff --git a/src/caches/low_order_rk_caches.jl b/lib/OrdinaryLowOrderRK/src/low_order_rk_caches.jl similarity index 98% rename from src/caches/low_order_rk_caches.jl rename to lib/OrdinaryLowOrderRK/src/low_order_rk_caches.jl index 0da22a8f41..2ac937b058 100644 --- a/src/caches/low_order_rk_caches.jl +++ b/lib/OrdinaryLowOrderRK/src/low_order_rk_caches.jl @@ -1535,3 +1535,27 @@ function alg_cache(alg::Alshina6, u, rate_prototype, ::Type{uEltypeNoUnits}, Alshina6Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, tmp, tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) end + +@cache struct FunctionMapCache{uType, rateType} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::rateType +end + +function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + FunctionMapCache(u, uprev, + FunctionMap_scale_by_time(alg) ? rate_prototype : + (eltype(u) <: Enum ? copy(u) : zero(u))) +end + +struct FunctionMapConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + FunctionMapConstantCache() +end \ No newline at end of file diff --git a/src/perform_step/low_order_rk_perform_step.jl b/lib/OrdinaryLowOrderRK/src/low_order_rk_perform_step.jl similarity index 99% rename from src/perform_step/low_order_rk_perform_step.jl rename to lib/OrdinaryLowOrderRK/src/low_order_rk_perform_step.jl index 8b8a0f63dd..1cd465607d 100644 --- a/src/perform_step/low_order_rk_perform_step.jl +++ b/lib/OrdinaryLowOrderRK/src/low_order_rk_perform_step.jl @@ -2323,4 +2323,4 @@ function perform_step!(integrator, cache::Alshina6Cache, repeat_step = false) integrator.stats.nf += 7 integrator.fsallast = k7 return nothing -end +end \ No newline at end of file diff --git a/src/tableaus/low_order_rk_tableaus.jl b/lib/OrdinaryLowOrderRK/src/low_order_rk_tableaus.jl similarity index 99% rename from src/tableaus/low_order_rk_tableaus.jl rename to lib/OrdinaryLowOrderRK/src/low_order_rk_tableaus.jl index 0dde8ad263..4e9e0069a0 100644 --- a/src/tableaus/low_order_rk_tableaus.jl +++ b/lib/OrdinaryLowOrderRK/src/low_order_rk_tableaus.jl @@ -2183,4 +2183,4 @@ function Alshina6ConstantCache(T, T2) Alshina6ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, b1, b5, b6, b7, c2, c3, c4, c5, c6, c7) -end +end \ No newline at end of file diff --git a/src/perform_step/split_perform_step.jl b/lib/OrdinaryLowOrderRK/src/split_perform_step.jl similarity index 99% rename from src/perform_step/split_perform_step.jl rename to lib/OrdinaryLowOrderRK/src/split_perform_step.jl index 80f7a906d7..aaa9a13783 100644 --- a/src/perform_step/split_perform_step.jl +++ b/lib/OrdinaryLowOrderRK/src/split_perform_step.jl @@ -47,4 +47,4 @@ end integrator.stats.nf2 += 1 integrator.stats.nf += 1 integrator.fsallast .+= cache.tmp -end +end \ No newline at end of file diff --git a/test/algconvergence/owrenzen_tests.jl b/lib/OrdinaryLowOrderRK/test/owrenzen_tests.jl similarity index 97% rename from test/algconvergence/owrenzen_tests.jl rename to lib/OrdinaryLowOrderRK/test/owrenzen_tests.jl index 35d4a5b3a9..96b6cb57d7 100644 --- a/test/algconvergence/owrenzen_tests.jl +++ b/lib/OrdinaryLowOrderRK/test/owrenzen_tests.jl @@ -40,4 +40,4 @@ sim = test_convergence(dts, prob, OwrenZen4(), dense_errors = true) @test sim.𝒪est[:L2]≈4 atol=testTol sim = test_convergence(dts, prob, OwrenZen5(), dense_errors = true) @test sim.𝒪est[:final]≈5 atol=testTol -@test sim.𝒪est[:L2]≈5 atol=testTol +@test sim.𝒪est[:L2]≈5 atol=testTol \ No newline at end of file diff --git a/lib/OrdinaryLowOrderRK/test/runtests.jl b/lib/OrdinaryLowOrderRK/test/runtests.jl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index ad9cfc295e..0a9930628c 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -145,25 +145,15 @@ include("nlsolve/functional.jl") include("nlsolve/newton.jl") include("caches/basic_caches.jl") -include("caches/low_order_rk_caches.jl") -include("caches/high_order_rk_caches.jl") -include("caches/sdirk_caches.jl") -include("caches/firk_caches.jl") -include("caches/kencarp_kvaerno_caches.jl") include("caches/linear_caches.jl") include("caches/linear_nonlinear_caches.jl") include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") -include("caches/bdf_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") include("caches/dae_caches.jl") include("caches/qprk_caches.jl") -include("tableaus/low_order_rk_tableaus.jl") -include("tableaus/high_order_rk_tableaus.jl") -include("tableaus/sdirk_tableaus.jl") -include("tableaus/firk_tableaus.jl") include("tableaus/qprk_tableaus.jl") include("integrators/type.jl") @@ -176,28 +166,18 @@ include("initialize_dae.jl") include("wrappers.jl") include("perform_step/fixed_timestep_perform_step.jl") -include("perform_step/split_perform_step.jl") include("perform_step/linear_perform_step.jl") include("perform_step/exponential_rk_perform_step.jl") include("perform_step/explicit_rk_perform_step.jl") -include("perform_step/low_order_rk_perform_step.jl") -include("perform_step/high_order_rk_perform_step.jl") -include("perform_step/sdirk_perform_step.jl") -include("perform_step/kencarp_kvaerno_perform_step.jl") -include("perform_step/firk_perform_step.jl") include("perform_step/composite_perform_step.jl") include("perform_step/adams_bashforth_moulton_perform_step.jl") include("perform_step/nordsieck_perform_step.jl") -include("perform_step/bdf_perform_step.jl") include("perform_step/prk_perform_step.jl") include("perform_step/pdirk_perform_step.jl") include("perform_step/dae_perform_step.jl") include("perform_step/qprk_perform_step.jl") include("dense/generic_dense.jl") -include("dense/interpolants.jl") -include("dense/low_order_rk_addsteps.jl") -include("dense/high_order_rk_addsteps.jl") include("derivative_utils.jl") include("nordsieck_utils.jl") @@ -281,6 +261,40 @@ export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, ROS3PRL2, ROK4a, ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 +include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") +using ..OrdinaryDiffEqBDF +export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, SBDF + MEBDF2 + +include("../lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl") +using ..OrdinaryDiffEqFIRK +export RadauIIA3, RadauIIA5 + +include("../lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl") +using ..OrdinaryDiffEqLowOrderRK +export Heun, Ralston, Midpoint, OwrenZen3, OwrenZen4, + OwrenZen5, RK4, BS3, BS5, Tsit5, DP5, Anas5, RKO65, + FRK65, RKM, MSRK5, MSRK6, PSRK4p7q6, PSRK3p6q5, + Stepanov5, SIR54, Alshina2, Alshina3, Alshina6, Euler, + PSRK3p5q4, SplitEuler + +include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") +using ..OrdinaryDiffEqSDIRK +export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, + Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, + Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, + SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, + SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA + +include("../lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryDiffEqHighOrderRK.jl") +using ..OrdinaryDiffEqHighOrderRK +export TanYam7, DP8, Tsitpap8, PFRK87 + +include("../lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl") +using ..OrdinaryDiffEqExplicitRK +export ExplicitRK + import PrecompileTools PrecompileTools.@compile_workload begin @@ -411,20 +425,8 @@ export constructDormandPrince # Reexport the Alg Types -export FunctionMap, Euler, Heun, Ralston, Midpoint, RK4, ExplicitRK, OwrenZen3, OwrenZen4, - OwrenZen5, - BS3, BS5, DP5, Tsit5, DP8, TanYam7, TsitPap8, CompositeAlgorithm, Anas5, RKO65, - FRK65, PFRK87, - RKM, MSRK5, MSRK6, Stepanov5, SIR54, QPRK98, PSRK4p7q6, PSRK3p6q5, PSRK3p5q4 - -export RadauIIA3, RadauIIA5 - -export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, - Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, - Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, - SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, - SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, - SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA +export FunctionMap, CompositeAlgorithm, + QPRK98 export MagnusMidpoint, LinearExponential, MagnusLeapfrog, LieEuler, CayleyEuler, MagnusGauss4, MagnusNC6, MagnusGL6, MagnusGL8, MagnusNC8, MagnusGL4, @@ -436,8 +438,6 @@ export LawsonEuler, NorsettEuler, ETD1, ETDRK2, ETDRK3, ETDRK4, HochOst4, Exp4, export SHLDDRK52, SHLDDRK_2N -export SplitEuler - export AB3, AB4, AB5, ABM32, ABM43, ABM54 export VCAB3, VCAB4, VCAB5, VCABM3, VCABM4, VCABM5 @@ -448,14 +448,8 @@ export IMEXEuler, IMEXEulerARK, CNAB2, CNLF2 export AN5, JVODE, JVODE_Adams, JVODE_BDF -export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF - export SBDF2, SBDF3, SBDF4 -export MEBDF2 - -export Alshina2, Alshina3, Alshina6 - export AutoSwitch, AutoTsit5, AutoDP5, AutoVern6, AutoVern7, AutoVern8, AutoVern9 diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 52498dd3d0..7ce6406509 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -26,20 +26,11 @@ SciMLBase.forwarddiffs_model_time(alg::RosenbrockAlgorithm) = true ## OrdinaryDiffEq Internal Traits isfsal(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = true -isfsal(tab::DiffEqBase.ExplicitRKTableau) = tab.fsal # isfsal(alg::CompositeAlgorithm) = isfsal(alg.algs[alg.current]) -isfsal(alg::FunctionMap) = false # Pseudo Non-FSAL isfsal(alg::PDIRK44) = false isfsal(alg::DImplicitEuler) = false -isfsal(alg::RKO65) = false -isfsal(alg::FRK65) = true -#isfsal(alg::RKM) = false - -isfsal(alg::PSRK3p5q4) = false -isfsal(alg::PSRK3p6q5) = false -isfsal(alg::PSRK4p7q6) = false get_current_isfsal(alg, cache) = isfsal(alg) @@ -161,12 +152,9 @@ function qmin_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) isadaptive(alg) ? 1 // 5 : 0 end qmin_default(alg::CompositeAlgorithm) = maximum(qmin_default.(alg.algs)) -qmin_default(alg::DP8) = 1 // 3 qmax_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 10 qmax_default(alg::CompositeAlgorithm) = minimum(qmax_default.(alg.algs)) -qmax_default(alg::DP8) = 6 -qmax_default(alg::Union{RadauIIA3, RadauIIA5}) = 8 function has_chunksize(alg::OrdinaryDiffEqAlgorithm) return alg isa Union{OrdinaryDiffEqExponentialAlgorithm, @@ -337,14 +325,8 @@ end alg_extrapolates(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_extrapolates(alg::CompositeAlgorithm) = any(alg_extrapolates.(alg.algs)) -alg_extrapolates(alg::ImplicitEuler) = true alg_extrapolates(alg::DImplicitEuler) = true alg_extrapolates(alg::DABDF2) = true -alg_extrapolates(alg::Trapezoid) = true -alg_extrapolates(alg::SDIRK22) = true -alg_extrapolates(alg::ABDF2) = true -alg_extrapolates(alg::SBDF) = true -alg_extrapolates(alg::MEBDF2) = true alg_extrapolates(alg::MagnusLeapfrog) = true function alg_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) @@ -364,10 +346,6 @@ function get_current_adaptive_order(alg::OrdinaryDiffEqAdamsVarOrderVarStepAlgor cache.order end get_current_alg_order(alg::JVODE, cache) = get_current_adaptive_order(alg, cache) -get_current_alg_order(alg::QNDF, cache) = cache.order -get_current_alg_order(alg::FBDF, cache) = cache.order -get_current_adaptive_order(alg::QNDF, cache) = cache.order -get_current_adaptive_order(alg::FBDF, cache) = cache.order #alg_adaptive_order(alg::OrdinaryDiffEqAdaptiveAlgorithm) = error("Algorithm is adaptive with no order") function get_current_adaptive_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}, @@ -378,10 +356,6 @@ function get_current_adaptive_order(alg::CompositeAlgorithm, cache) _eval_index(alg_adaptive_order, alg.algs, cache.current)::Int end -alg_order(alg::FunctionMap) = 0 -alg_order(alg::Euler) = 1 -alg_order(alg::Heun) = 2 -alg_order(alg::Ralston) = 2 alg_order(alg::LawsonEuler) = 1 alg_order(alg::NorsettEuler) = 1 alg_order(alg::LieEuler) = 1 @@ -397,41 +371,11 @@ alg_order(alg::EPIRK5s3) = 5 alg_order(alg::EPIRK5P1) = 5 alg_order(alg::EPIRK5P2) = 5 alg_order(alg::EXPRB53s3) = 5 -alg_order(alg::SplitEuler) = 1 alg_order(alg::ETD2) = 2 alg_order(alg::Exprb32) = 3 alg_order(alg::Exprb43) = 4 -alg_order(alg::Anas5) = 5 alg_order(alg::KuttaPRK2p5) = 5 -alg_order(alg::RKO65) = 5 -alg_order(alg::FRK65) = 6 - -alg_order(alg::Midpoint) = 2 - -alg_order(alg::RK4) = 4 -alg_order(alg::RKM) = 4 -alg_order(alg::ExplicitRK) = alg.tableau.order -alg_order(alg::MSRK5) = 5 -alg_order(alg::MSRK6) = 6 -alg_order(alg::Stepanov5) = 5 -alg_order(alg::SIR54) = 5 -alg_order(alg::PSRK4p7q6) = 4 -alg_order(alg::PSRK3p6q5) = 3 -alg_order(alg::PSRK3p5q4) = 3 - -alg_order(alg::BS3) = 3 -alg_order(alg::BS5) = 5 -alg_order(alg::OwrenZen3) = 3 -alg_order(alg::OwrenZen4) = 4 -alg_order(alg::OwrenZen5) = 5 -alg_order(alg::DP5) = 5 -alg_order(alg::Tsit5) = 5 -alg_order(alg::DP8) = 8 -alg_order(alg::TanYam7) = 7 -alg_order(alg::TsitPap8) = 8 -alg_order(alg::RadauIIA3) = 3 -alg_order(alg::RadauIIA5) = 5 -alg_order(alg::ImplicitEuler) = 1 + alg_order(alg::RKMK2) = 2 alg_order(alg::RKMK4) = 4 alg_order(alg::LieRK4) = 4 @@ -448,35 +392,6 @@ alg_order(alg::MagnusGL4) = 4 alg_order(alg::MagnusAdapt4) = 4 alg_order(alg::LinearExponential) = 1 alg_order(alg::MagnusLeapfrog) = 2 -alg_order(alg::Trapezoid) = 2 -alg_order(alg::ImplicitMidpoint) = 2 -alg_order(alg::TRBDF2) = 2 -alg_order(alg::SSPSDIRK2) = 2 -alg_order(alg::SDIRK2) = 2 -alg_order(alg::SDIRK22) = 2 -alg_order(alg::Kvaerno3) = 3 -alg_order(alg::Kvaerno4) = 4 -alg_order(alg::Kvaerno5) = 5 -alg_order(alg::ESDIRK54I8L2SA) = 5 -alg_order(alg::ESDIRK436L2SA2) = 4 -alg_order(alg::ESDIRK437L2SA) = 4 -alg_order(alg::ESDIRK547L2SA2) = 5 -alg_order(alg::ESDIRK659L2SA) = 6 -alg_order(alg::KenCarp3) = 3 -alg_order(alg::CFNLIRK3) = 3 -alg_order(alg::KenCarp4) = 4 -alg_order(alg::KenCarp47) = 4 -alg_order(alg::KenCarp5) = 5 -alg_order(alg::KenCarp58) = 5 -alg_order(alg::Cash4) = 4 -alg_order(alg::SFSDIRK4) = 4 -alg_order(alg::SFSDIRK5) = 4 -alg_order(alg::SFSDIRK6) = 4 -alg_order(alg::SFSDIRK7) = 4 -alg_order(alg::SFSDIRK8) = 4 -alg_order(alg::Hairer4) = 4 -alg_order(alg::Hairer42) = 4 -alg_order(alg::PFRK87) = 8 alg_order(alg::AB3) = 3 alg_order(alg::AB4) = 4 @@ -500,42 +415,20 @@ alg_order(alg::CNLF2) = 2 alg_order(alg::AN5) = 5 alg_order(alg::JVODE) = 1 #dummy value -alg_order(alg::ABDF2) = 2 -alg_order(alg::QNDF1) = 1 -alg_order(alg::QNDF2) = 2 - -alg_order(alg::QNDF) = 1 #dummy value -alg_order(alg::FBDF) = 1 #dummy value - -alg_order(alg::SBDF) = alg.order - -alg_order(alg::MEBDF2) = 2 alg_order(alg::PDIRK44) = 4 alg_order(alg::DImplicitEuler) = 1 alg_order(alg::DABDF2) = 2 alg_order(alg::DFBDF) = 1#dummy value - -alg_order(alg::Alshina2) = 2 -alg_order(alg::Alshina3) = 3 -alg_order(alg::Alshina6) = 6 - alg_order(alg::QPRK98) = 9 alg_maximum_order(alg) = alg_order(alg) alg_maximum_order(alg::CompositeAlgorithm) = maximum(alg_order(x) for x in alg.algs) -alg_adaptive_order(alg::ExplicitRK) = alg.tableau.adaptiveorder alg_adaptive_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = alg_order(alg) - 1 -alg_adaptive_order(alg::RadauIIA3) = 1 -alg_adaptive_order(alg::RadauIIA5) = 3 - -alg_adaptive_order(alg::ImplicitEuler) = 0 -alg_adaptive_order(alg::Trapezoid) = 1 # this is actually incorrect and is purposefully decreased as this tends # to track the real error much better -alg_adaptive_order(alg::ImplicitMidpoint) = 1 # this is actually incorrect and is purposefully decreased as this tends # to track the real error much better @@ -576,16 +469,10 @@ end function beta2_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) isadaptive(alg) ? 2 // (5alg_order(alg)) : 0 end -beta2_default(alg::FunctionMap) = 0 -beta2_default(alg::DP8) = 0 // 1 -beta2_default(alg::DP5) = 4 // 100 function beta1_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}, beta2) isadaptive(alg) ? 7 // (10alg_order(alg)) : 0 end -beta1_default(alg::FunctionMap, beta2) = 0 -beta1_default(alg::DP8, beta2) = typeof(beta2)(1 // alg_order(alg)) - beta2 / 5 -beta1_default(alg::DP5, beta2) = typeof(beta2)(1 // alg_order(alg)) - 3beta2 / 4 function gamma_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) isadaptive(alg) ? 9 // 10 : 0 @@ -595,17 +482,12 @@ gamma_default(alg::CompositeAlgorithm) = maximum(gamma_default, alg.algs) fac_default_gamma(alg) = false qsteady_min_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 1 -qsteady_min_default(alg::FBDF) = 9 // 10 qsteady_max_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 1 qsteady_max_default(alg::OrdinaryDiffEqAdaptiveImplicitAlgorithm) = 6 // 5 # But don't re-use Jacobian if not adaptive: too risky and cannot pull back qsteady_max_default(alg::OrdinaryDiffEqImplicitAlgorithm) = isadaptive(alg) ? 1 // 1 : 0 qsteady_max_default(alg::AN5) = 3 // 2 qsteady_max_default(alg::JVODE) = 3 // 2 -qsteady_max_default(alg::QNDF1) = 2 // 1 -qsteady_max_default(alg::QNDF2) = 2 // 1 -qsteady_max_default(alg::QNDF) = 2 // 1 -qsteady_max_default(alg::FBDF) = 2 // 1 #TODO #DiffEqBase.nlsolve_default(::QNDF, ::Val{κ}) = 1//2 @@ -616,16 +498,11 @@ end # SSP coefficients ssp_coefficient(alg) = error("$alg is not a strong stability preserving method.") -ssp_coefficient(alg::Euler) = 1 # We shouldn't do this probably. #ssp_coefficient(alg::ImplicitEuler) = Inf -ssp_coefficient(alg::SSPSDIRK2) = 4 # stability regions -alg_stability_size(alg::ExplicitRK) = alg.tableau.stability_size -alg_stability_size(alg::DP5) = 3.3066 -alg_stability_size(alg::Tsit5) = 3.5068 alg_can_repeat_jac(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_can_repeat_jac(alg::OrdinaryDiffEqNewtonAdaptiveAlgorithm) = true @@ -689,14 +566,6 @@ isstandard(alg::OrdinaryDiffEqNewtonAdaptiveAlgorithm) = alg.controller === :Sta isstandard(alg::VCABM) = true isWmethod(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false - -isesdirk(alg::TRBDF2) = true -function isesdirk(alg::Union{KenCarp3, KenCarp4, KenCarp5, KenCarp58, - Kvaerno3, Kvaerno4, Kvaerno5, ESDIRK437L2SA, - ESDIRK54I8L2SA, ESDIRK436L2SA2, ESDIRK547L2SA2, - ESDIRK659L2SA, CFNLIRK3}) - true -end isesdirk(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false diff --git a/src/algorithms.jl b/src/algorithms.jl index 1899299f5e..2b1f4226de 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -46,9 +46,6 @@ abstract type OrdinaryDiffEqAdaptivePartitionedAlgorithm <: OrdinaryDiffEqAdapti const PartitionedAlgorithm = Union{OrdinaryDiffEqPartitionedAlgorithm, OrdinaryDiffEqAdaptivePartitionedAlgorithm} -struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end -FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() - function DiffEqBase.remake(thing::OrdinaryDiffEqAlgorithm; kwargs...) T = SciMLBase.remaker_of(thing) T(; SciMLBase.struct_as_namedtuple(thing)..., kwargs...) @@ -73,238 +70,6 @@ end # RK methods -struct ExplicitRK{TabType} <: OrdinaryDiffEqAdaptiveAlgorithm - tableau::TabType -end -ExplicitRK(; tableau = ODE_DEFAULT_TABLEAU) = ExplicitRK(tableau) - -TruncatedStacktraces.@truncate_stacktrace ExplicitRK - -@inline trivial_limiter!(u, integrator, p, t) = nothing -""" - SIR54(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -5th order Explicit RK method suited for SIR-type epidemic models. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Kovalnogov2020RungeKuttaPS, -title={Runge–Kutta pairs suited for SIR‐type epidemic models}, -author={Vladislav N. Kovalnogov and Theodore E. Simos and Ch. Tsitouras}, -journal={Mathematical Methods in the Applied Sciences}, -year={2020}, -volume={44}, -pages={5210 - 5216} -} -""" -struct SIR54{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function SIR54(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - SIR54{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -# for backwards compatibility -function SIR54(stage_limiter!, step_limiter! = trivial_limiter!) - SIR54{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::SIR54) - print(io, "SIR54(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - -""" - Alshina2(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -2nd order, 2-stage Explicit Runge-Kutta Method with optimal parameters. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Alshina2008, -doi = {10.1134/s0965542508030068}, -url = {https://doi.org/10.1134/s0965542508030068}, -year = {2008}, -month = mar, -publisher = {Pleiades Publishing Ltd}, -volume = {48}, -number = {3}, -pages = {395--405}, -author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, -title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, -journal = {Computational Mathematics and Mathematical Physics} -} -""" -struct Alshina2{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function Alshina2(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - Alshina2{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -function Alshina2(stage_limiter!, step_limiter! = trivial_limiter!) - Alshina2{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::Alshina2) - print(io, "Alshina2(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - -""" - Alshina3(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -3rd order, 3-stage Explicit Runge-Kutta Method with optimal parameters. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Alshina2008, -doi = {10.1134/s0965542508030068}, -url = {https://doi.org/10.1134/s0965542508030068}, -year = {2008}, -month = mar, -publisher = {Pleiades Publishing Ltd}, -volume = {48}, -number = {3}, -pages = {395--405}, -author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, -title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, -journal = {Computational Mathematics and Mathematical Physics} -} -""" -struct Alshina3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function Alshina3(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - Alshina3{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -function Alshina3(stage_limiter!, step_limiter! = trivial_limiter!) - Alshina3{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::Alshina3) - print(io, "Alshina3(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - -""" - Alshina6(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -6th order, 7-stage Explicit Runge-Kutta Method with optimal parameters. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Alshina2008, -doi = {10.1134/s0965542508030068}, -url = {https://doi.org/10.1134/s0965542508030068}, -year = {2008}, -month = mar, -publisher = {Pleiades Publishing Ltd}, -volume = {48}, -number = {3}, -pages = {395--405}, -author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, -title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, -journal = {Computational Mathematics and Mathematical Physics} -} -""" -struct Alshina6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function Alshina6(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - Alshina6{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -function Alshina6(stage_limiter!, step_limiter! = trivial_limiter!) - Alshina6{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::Alshina6) - print(io, "Alshina6(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - ################################################################################ # Adams Bashforth and Adams moulton methods @@ -490,41 +255,6 @@ function CNLF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Va extrapolant) end -""" -QNDF1: Multistep Method -An adaptive order 1 quasi-constant timestep L-stable numerical differentiation function (NDF) method. -Optional parameter kappa defaults to Shampine's accuracy-optimal -0.1850. - -See also `QNDF`. -""" -struct QNDF1{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, kappa = -0.1850, - controller = :Standard, step_limiter! = trivial_limiter!) - QNDF1{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(kappa), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - kappa, - controller, - step_limiter!) -end - """ QBDF1: Multistep Method @@ -532,40 +262,6 @@ An alias of `QNDF1` with κ=0. """ QBDF1(; kwargs...) = QNDF1(; kappa = 0, kwargs...) -""" -QNDF2: Multistep Method -An adaptive order 2 quasi-constant timestep L-stable numerical differentiation function (NDF) method. - -See also `QNDF`. -""" -struct QNDF2{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, kappa = -1 // 9, - controller = :Standard, step_limiter! = trivial_limiter!) - QNDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(kappa), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - kappa, - controller, - step_limiter!) -end - """ QBDF2: Multistep Method @@ -573,51 +269,6 @@ An alias of `QNDF2` with κ=0. """ QBDF2(; kwargs...) = QNDF2(; kappa = 0, kwargs...) -""" -QNDF: Multistep Method -An adaptive order quasi-constant timestep NDF method. -Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). - -@article{shampine1997matlab, -title={The matlab ode suite}, -author={Shampine, Lawrence F and Reichelt, Mark W}, -journal={SIAM journal on scientific computing}, -volume={18}, -number={1}, -pages={1--22}, -year={1997}, -publisher={SIAM} -} -""" -struct QNDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, kappa = promote(-0.1850, -1 // 9, -0.0823, -0.0415, 0), - controller = :Standard, step_limiter! = trivial_limiter!) where {MO} - QNDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(kappa), typeof(step_limiter!)}( - max_order, linsolve, nlsolve, precs, κ, tol, - extrapolant, kappa, controller, step_limiter!) -end - TruncatedStacktraces.@truncate_stacktrace QNDF """ @@ -627,101 +278,6 @@ An alias of `QNDF` with κ=0. """ QBDF(; kwargs...) = QNDF(; kappa = tuple(0 // 1, 0 // 1, 0 // 1, 0 // 1, 0 // 1), kwargs...) -""" -FBDF: Fixed leading coefficient BDF - -An adaptive order quasi-constant timestep NDF method. -Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). - -@article{shampine2002solving, -title={Solving 0= F (t, y (t), y′(t)) in Matlab}, -author={Shampine, Lawrence F}, -year={2002}, -publisher={Walter de Gruyter GmbH \\& Co. KG} -} -""" -struct FBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function FBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard, step_limiter! = trivial_limiter!) where {MO} - FBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(step_limiter!)}( - max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace FBDF - -""" -Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. Implicit-Explicit Methods for Time- -Dependent Partial Differential Equations. 1995 Society for Industrial and Applied Mathematics -Journal on Numerical Analysis, 32(3), pp 797-823, 1995. doi: https://doi.org/10.1137/0732037 -""" -struct SBDF{CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - order::Int - ark::Bool -end - -function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, ark = false) - SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(linsolve, - nlsolve, - precs, - κ, - tol, - extrapolant, - order, - ark) -end - -# All keyword form needed for remake -function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, - order, ark = false) - SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(linsolve, - nlsolve, - precs, - κ, - tol, - extrapolant, - order, - ark) -end - """ IMEXEuler(;kwargs...) @@ -888,1092 +444,87 @@ struct CayleyEuler <: OrdinaryDiffEqAlgorithm end ################################################################################ -# FIRK Methods +################################################################################ -""" -@article{hairer1999stiff, -title={Stiff differential equations solved by Radau methods}, -author={Hairer, Ernst and Wanner, Gerhard}, -journal={Journal of Computational and Applied Mathematics}, -volume={111}, -number={1-2}, -pages={93--111}, -year={1999}, -publisher={Elsevier} -} - -RadauIIA3: Fully-Implicit Runge-Kutta Method -An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. -""" -struct RadauIIA3{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - extrapolant::Symbol - κ::Tol - maxiters::Int - fast_convergence_cutoff::C1 - new_W_γdt_cutoff::C2 - controller::Symbol - step_limiter!::StepLimiter -end +###################################### -function RadauIIA3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, - extrapolant = :dense, fast_convergence_cutoff = 1 // 5, - new_W_γdt_cutoff = 1 // 5, - controller = :Predictive, κ = nothing, maxiters = 10, - step_limiter! = trivial_limiter!) - RadauIIA3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(fast_convergence_cutoff), - typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, - precs, - extrapolant, - κ, - maxiters, - fast_convergence_cutoff, - new_W_γdt_cutoff, - controller, - step_limiter!) +for Alg in [:LawsonEuler, :NorsettEuler, :ETDRK2, :ETDRK3, :ETDRK4, :HochOst4] + """ + Hochbruck, Marlis, and Alexander Ostermann. “Exponential Integrators.” Acta + Numerica 19 (2010): 209–286. doi:10.1017/S0962492910000048. + """ + @eval struct $Alg{CS, AD, FDT, ST, CJ} <: + OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} + krylov::Bool + m::Int + iop::Int + end + @eval function $Alg(; krylov = false, m = 30, iop = 0, autodiff = true, + standardtag = Val{true}(), concrete_jac = nothing, + chunk_size = Val{0}(), + diff_type = Val{:forward}) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), + diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(krylov, + m, + iop) + end +end +const ETD1 = NorsettEuler # alias +for Alg in [:Exprb32, :Exprb43] + @eval struct $Alg{CS, AD, FDT, ST, CJ} <: + OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD, FDT, ST, CJ} + m::Int + iop::Int + end + @eval function $Alg(; m = 30, iop = 0, autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, chunk_size = Val{0}(), + diff_type = Val{:forward}) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), + diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(m, + iop) + end +end +for Alg in [:Exp4, :EPIRK4s3A, :EPIRK4s3B, :EPIRK5s3, :EXPRB53s3, :EPIRK5P1, :EPIRK5P2] + @eval struct $Alg{CS, AD, FDT, ST, CJ} <: + OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} + adaptive_krylov::Bool + m::Int + iop::Int + end + @eval function $Alg(; adaptive_krylov = true, m = 30, iop = 0, autodiff = true, + standardtag = Val{true}(), concrete_jac = nothing, + chunk_size = Val{0}(), diff_type = Val{:forward}) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), diff_type, + _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(adaptive_krylov, + m, + iop) + end end - -TruncatedStacktraces.@truncate_stacktrace RadauIIA3 - """ -@article{hairer1999stiff, -title={Stiff differential equations solved by Radau methods}, -author={Hairer, Ernst and Wanner, Gerhard}, -journal={Journal of Computational and Applied Mathematics}, -volume={111}, -number={1-2}, -pages={93--111}, -year={1999}, -publisher={Elsevier} -} - -RadauIIA5: Fully-Implicit Runge-Kutta Method -An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. +ETD2: Exponential Runge-Kutta Method +Second order Exponential Time Differencing method (in development). """ -struct RadauIIA5{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - smooth_est::Bool - extrapolant::Symbol - κ::Tol - maxiters::Int - fast_convergence_cutoff::C1 - new_W_γdt_cutoff::C2 - controller::Symbol - step_limiter!::StepLimiter -end +struct ETD2 <: + OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end -function RadauIIA5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, - extrapolant = :dense, fast_convergence_cutoff = 1 // 5, - new_W_γdt_cutoff = 1 // 5, - controller = :Predictive, κ = nothing, maxiters = 10, smooth_est = true, - step_limiter! = trivial_limiter!) - RadauIIA5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(fast_convergence_cutoff), - typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, - precs, - smooth_est, - extrapolant, - κ, - maxiters, - fast_convergence_cutoff, - new_W_γdt_cutoff, - controller, - step_limiter!) -end -TruncatedStacktraces.@truncate_stacktrace RadauIIA5 +######################################### -################################################################################ +######################################### -# SDIRK Methods -""" -ImplicitEuler: SDIRK Method -A 1st order implicit solver. A-B-L-stable. Adaptive timestepping through a divided differences estimate via memory. -Strong-stability preserving (SSP). -""" -struct ImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter +struct CompositeAlgorithm{CS, T, F} <: OrdinaryDiffEqCompositeAlgorithm + algs::T + choice_function::F + function CompositeAlgorithm(algs::T, choice_function::F) where {T, F} + CS = mapreduce(alg -> has_chunksize(alg) ? get_chunksize_int(alg) : 0, max, algs) + new{CS, T, F}(algs, choice_function) + end end -function ImplicitEuler(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :PI, step_limiter! = trivial_limiter!) - ImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, precs, extrapolant, controller, step_limiter!) -end -""" -ImplicitMidpoint: SDIRK Method -A second order A-stable symplectic and symmetric implicit solver. -Good for highly stiff equations which need symplectic integration. -""" -struct ImplicitMidpoint{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - step_limiter!::StepLimiter -end - -function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, step_limiter! = trivial_limiter!) - ImplicitMidpoint{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - step_limiter!) -end - -""" -Andre Vladimirescu. 1994. The Spice Book. John Wiley & Sons, Inc., New York, -NY, USA. - -Trapezoid: SDIRK Method -A second order A-stable symmetric ESDIRK method. -"Almost symplectic" without numerical dampening. -Also known as Crank-Nicolson when applied to PDEs. Adaptive timestepping via divided -differences approximation to the second derivative terms in the local truncation error -estimate (the SPICE approximation strategy). -""" -struct Trapezoid{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function Trapezoid(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - controller, - step_limiter!) -end - -""" -@article{hosea1996analysis, -title={Analysis and implementation of TR-BDF2}, -author={Hosea, ME and Shampine, LF}, -journal={Applied Numerical Mathematics}, -volume={20}, -number={1-2}, -pages={21--37}, -year={1996}, -publisher={Elsevier} -} - -TRBDF2: SDIRK Method -A second order A-B-L-S-stable one-step ESDIRK method. -Includes stiffness-robust error estimates for accurate adaptive timestepping, smoothed derivatives for highly stiff and oscillatory problems. -""" -struct TRBDF2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function TRBDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - TRBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace TRBDF2 - -""" -@article{hindmarsh2005sundials, -title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, -author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, -journal={ACM Transactions on Mathematical Software (TOMS)}, -volume={31}, -number={3}, -pages={363--396}, -year={2005}, -publisher={ACM} -} - -SDIRK2: SDIRK Method -An A-B-L stable 2nd order SDIRK method -""" -struct SDIRK2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function SDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - SDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}( - linsolve, nlsolve, precs, smooth_est, extrapolant, - controller, - step_limiter!) -end - -struct SDIRK22{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function SDIRK22(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - controller, - step_limiter!) -end - -struct SSPSDIRK2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} # Not adaptive - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end - -function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :constant, - controller = :PI) - SSPSDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno3: SDIRK Method -An A-L stable stiffly-accurate 3rd order ESDIRK method -""" -struct Kvaerno3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp3: SDIRK Method -An A-L stable stiffly-accurate 3rd order ESDIRK method with splitting -""" -struct KenCarp3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -struct CFNLIRK3{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function CFNLIRK3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - CFNLIRK3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -""" -@article{hindmarsh2005sundials, -title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, -author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, -journal={ACM Transactions on Mathematical Software (TOMS)}, -volume={31}, -number={3}, -pages={363--396}, -year={2005}, -publisher={ACM} -} - -Cash4: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Cash4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - embedding::Int - controller::Symbol -end -function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, embedding = 3) - Cash4{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( - linsolve, - nlsolve, - precs, - smooth_est, - extrapolant, - embedding, - controller) -end - -struct SFSDIRK4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function SFSDIRK4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK5{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK6{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK6(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK6{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK7{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK7(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK7{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK8{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK8(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK8{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -""" -E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and -differential-algebraic problems. Computational mathematics (2nd revised ed.), -Springer (1996) - -Hairer4: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Hairer4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function Hairer4(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - Hairer4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and -differential-algebraic problems. Computational mathematics (2nd revised ed.), -Springer (1996) - -Hairer42: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Hairer42{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function Hairer42(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - Hairer42{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno4: SDIRK Method -An A-L stable stiffly-accurate 4th order ESDIRK method. -""" -struct Kvaerno4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno5: SDIRK Method -An A-L stable stiffly-accurate 5th order ESDIRK method -""" -struct Kvaerno5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp4: SDIRK Method -An A-L stable stiffly-accurate 4th order ESDIRK method with splitting -""" -struct KenCarp4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace KenCarp4 - -""" -@article{kennedy2019higher, -title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, -author={Kennedy, Christopher A and Carpenter, Mark H}, -journal={Applied Numerical Mathematics}, -volume={136}, -pages={183--205}, -year={2019}, -publisher={Elsevier} -} - -KenCarp47: SDIRK Method -An A-L stable stiffly-accurate 4th order seven-stage ESDIRK method with splitting -""" -struct KenCarp47{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function KenCarp47(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - KenCarp47{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp5: SDIRK Method -An A-L stable stiffly-accurate 5th order ESDIRK method with splitting -""" -struct KenCarp5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end -""" -@article{kennedy2019higher, -title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, -author={Kennedy, Christopher A and Carpenter, Mark H}, -journal={Applied Numerical Mathematics}, -volume={136}, -pages={183--205}, -year={2019}, -publisher={Elsevier} -} - -KenCarp58: SDIRK Method -An A-L stable stiffly-accurate 5th order eight-stage ESDIRK method with splitting -""" -struct KenCarp58{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function KenCarp58(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - KenCarp58{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -# `smooth_est` is not necessary, as the embedded method is also L-stable -struct ESDIRK54I8L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK54I8L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK436L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK436L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK437L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK437L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK547L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK547L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} - -Currently has STABILITY ISSUES, causing it to fail the adaptive tests. -Check issue https://github.com/SciML/OrdinaryDiffEq.jl/issues/1933 for more details. -} -""" -struct ESDIRK659L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK659L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -###################################### - -for Alg in [:LawsonEuler, :NorsettEuler, :ETDRK2, :ETDRK3, :ETDRK4, :HochOst4] - """ - Hochbruck, Marlis, and Alexander Ostermann. “Exponential Integrators.” Acta - Numerica 19 (2010): 209–286. doi:10.1017/S0962492910000048. - """ - @eval struct $Alg{CS, AD, FDT, ST, CJ} <: - OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} - krylov::Bool - m::Int - iop::Int - end - @eval function $Alg(; krylov = false, m = 30, iop = 0, autodiff = true, - standardtag = Val{true}(), concrete_jac = nothing, - chunk_size = Val{0}(), - diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), - diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(krylov, - m, - iop) - end -end -const ETD1 = NorsettEuler # alias -for Alg in [:Exprb32, :Exprb43] - @eval struct $Alg{CS, AD, FDT, ST, CJ} <: - OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD, FDT, ST, CJ} - m::Int - iop::Int - end - @eval function $Alg(; m = 30, iop = 0, autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, chunk_size = Val{0}(), - diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), - diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(m, - iop) - end -end -for Alg in [:Exp4, :EPIRK4s3A, :EPIRK4s3B, :EPIRK5s3, :EXPRB53s3, :EPIRK5P1, :EPIRK5P2] - @eval struct $Alg{CS, AD, FDT, ST, CJ} <: - OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} - adaptive_krylov::Bool - m::Int - iop::Int - end - @eval function $Alg(; adaptive_krylov = true, m = 30, iop = 0, autodiff = true, - standardtag = Val{true}(), concrete_jac = nothing, - chunk_size = Val{0}(), diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), diff_type, - _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(adaptive_krylov, - m, - iop) - end -end -struct SplitEuler <: - OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end -""" -ETD2: Exponential Runge-Kutta Method -Second order Exponential Time Differencing method (in development). -""" -struct ETD2 <: - OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end - -######################################### - -""" -E. Alberdi Celayaa, J. J. Anza Aguirrezabalab, P. Chatzipantelidisc. Implementation of -an Adaptive BDF2 Formula and Comparison with The MATLAB Ode15s. Procedia Computer Science, -29, pp 1014-1026, 2014. doi: https://doi.org/10.1016/j.procs.2014.05.091 - -ABDF2: Multistep Method -An adaptive order 2 L-stable fixed leading coefficient multistep BDF method. -""" -struct ABDF2{CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function ABDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - κ = nothing, tol = nothing, linsolve = nothing, precs = DEFAULT_PRECS, - nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :Standard, step_limiter! = trivial_limiter!) - ABDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(step_limiter!)}(linsolve, nlsolve, precs, κ, tol, - smooth_est, extrapolant, controller, step_limiter!) -end - -######################################### - -struct CompositeAlgorithm{CS, T, F} <: OrdinaryDiffEqCompositeAlgorithm - algs::T - choice_function::F - function CompositeAlgorithm(algs::T, choice_function::F) where {T, F} - CS = mapreduce(alg -> has_chunksize(alg) ? get_chunksize_int(alg) : 0, max, algs) - new{CS, T, F}(algs, choice_function) - end -end - -TruncatedStacktraces.@truncate_stacktrace CompositeAlgorithm 1 - -if isdefined(Base, :Experimental) && isdefined(Base.Experimental, :silence!) - Base.Experimental.silence!(CompositeAlgorithm) +TruncatedStacktraces.@truncate_stacktrace CompositeAlgorithm 1 + +if isdefined(Base, :Experimental) && isdefined(Base.Experimental, :silence!) + Base.Experimental.silence!(CompositeAlgorithm) end mutable struct AutoSwitchCache{nAlg, sAlg, tolType, T} @@ -2031,30 +582,7 @@ struct AutoSwitch{nAlg, sAlg, tolType, T} switch_max::Int end -################################################################################ -""" -MEBDF2: Multistep Method -The second order Modified Extended BDF method, which has improved stability properties over the standard BDF. -Fixed timestep only. -""" -struct MEBDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function MEBDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant) - MEBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end +############################################################################### ################################################# """ diff --git a/src/algorithms/explicit_rk.jl b/src/algorithms/explicit_rk.jl index aed2bc29b7..086d0fcbd6 100644 --- a/src/algorithms/explicit_rk.jl +++ b/src/algorithms/explicit_rk.jl @@ -6,472 +6,9 @@ function Base.show(io::IO, alg::OrdinaryDiffEqAlgorithm) print(io, ")") end -@doc explicit_rk_docstring( - "The second order Heun's method. Uses embedded Euler method for adaptivity.", - "Heun") -Base.@kwdef struct Heun{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Heun(stage_limiter!, step_limiter! = trivial_limiter!) - Heun(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "The optimized second order midpoint method. Uses embedded Euler method for adaptivity.", - "Ralston") -Base.@kwdef struct Ralston{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Ralston(stage_limiter!, step_limiter! = trivial_limiter!) - Ralston(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "The second order midpoint method. Uses embedded Euler method for adaptivity.", - "Midpoint") -Base.@kwdef struct Midpoint{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Midpoint(stage_limiter!, step_limiter! = trivial_limiter!) - Midpoint(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("The canonical Runge-Kutta Order 4 method. -Uses a defect control for adaptive stepping using maximum error over the whole interval.", - "RK4", - references = "@article{shampine2005solving, - title={Solving ODEs and DDEs with residual control}, - author={Shampine, LF}, - journal={Applied Numerical Mathematics}, - volume={52}, - number={1}, - pages={113--127}, - year={2005}, - publisher={Elsevier} - }") -Base.@kwdef struct RK4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function RK4(stage_limiter!, step_limiter! = trivial_limiter!) - RK4(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("TBD", "RKM") -Base.@kwdef struct RKM{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function RKM(stage_limiter!, step_limiter! = trivial_limiter!) - RKM(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("4-stage Pseudo-Symplectic Explicit RK method.", "3p5q(4)", - references = "@article{Aubry1998, - author = {A. Aubry and P. Chartier}, - journal = {BIT Numer. Math.}, - title = {Pseudo-symplectic {R}unge-{K}utta methods}, - year = {1998}, - }, - @article{Capuano2017, - title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, - journal = {J. Comput. Phys.}, - year = {2017}, - author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") -Base.@kwdef struct PSRK3p5q4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end - -@doc explicit_rk_docstring("5-stage Pseudo-Symplectic Explicit RK method.", "3p6q(5)", - references = "@article{Aubry1998, - author = {A. Aubry and P. Chartier}, - journal = {BIT Numer. Math.}, - title = {Pseudo-symplectic {R}unge-{K}utta methods}, - year = {1998}, - }, - @article{Capuano2017, - title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, - journal = {J. Comput. Phys.}, - year = {2017}, - author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") -Base.@kwdef struct PSRK3p6q5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end - -@doc explicit_rk_docstring("6-stage Pseudo-Symplectic Explicit RK method.", "4p7q(6)", - references = "@article{Aubry1998, - author = {A. Aubry and P. Chartier}, - journal = {BIT Numer. Math.}, - title = {Pseudo-symplectic {R}unge-{K}utta methods}, - volume = {38}, - PAGES = {439-461}, - year = {1998}, - }, - @article{Capuano2017, - title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, - journal = {J. Comput. Phys.}, - volume = {328}, - pages = {86-94}, - year = {2017}, - issn = {0021-9991}, - doi = {https://doi.org/10.1016/j.jcp.2016.10.040}, - author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") -Base.@kwdef struct PSRK4p7q6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end - -@doc explicit_rk_docstring("5th order Explicit RK method.", "MSRK5", - references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Figure 3.") -Base.@kwdef struct MSRK5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function MSRK5(stage_limiter!, step_limiter! = trivial_limiter!) - MSRK5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("6th order Explicit RK method.", "MSRK6", - references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Table4") -Base.@kwdef struct MSRK6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function MSRK6(stage_limiter!, step_limiter! = trivial_limiter!) - MSRK6(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("5th order Explicit RK method.", - "Stepanov5", - references = "@article{Stepanov2021Embedded5, - title={Embedded (4, 5) pairs of explicit 7-stage Runge–Kutta methods with FSAL property}, - author={Misha Stepanov}, - journal={Calcolo}, - year={2021}, - volume={59} - }") -Base.@kwdef struct Stepanov5{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Stepanov5(stage_limiter!, step_limiter! = trivial_limiter!) - Stepanov5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("4th order Runge-Kutta method designed for periodic problems.", - "Anas5", - extra_keyword_description = """- `w`: a periodicity estimate, which when accurate the method becomes 5th order - (and is otherwise 4th order with less error for better estimates). - """, - extra_keyword_default = "w = 1") -Base.@kwdef struct Anas5{StageLimiter, StepLimiter, Thread, T} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - w::T = 1 -end -# for backwards compatibility -function Anas5(stage_limiter!, step_limiter! = trivial_limiter!; w = 1) - Anas5(stage_limiter!, step_limiter!, False(), w) -end - -@doc explicit_rk_docstring("5th order Explicit RK method.", "RKO5", - references = "Tsitouras, Ch. \"Explicit Runge–Kutta methods for starting integration of - Lane–Emden problem.\" Applied Mathematics and Computation 354 (2019): 353-364. - doi: https://doi.org/10.1016/j.amc.2019.02.047") -Base.@kwdef struct RKO65{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function RKO65(stage_limiter!, step_limiter! = trivial_limiter!) - RKO65(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Owren-Zennaro optimized interpolation 3/2 method (free 3rd order interpolant).", - "OwrenZen3", - references = "@article{owren1992derivation, - title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, - author={Owren, Brynjulf and Zennaro, Marino}, - journal={SIAM journal on scientific and statistical computing}, - volume={13}, - number={6}, - pages={1488--1501}, - year={1992}, - publisher={SIAM} - }") -Base.@kwdef struct OwrenZen3{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function OwrenZen3(stage_limiter!, step_limiter! = trivial_limiter!) - OwrenZen3(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Owren-Zennaro optimized interpolation 4/3 method (free 4th order interpolant).", - "OwrenZen4", - references = "@article{owren1992derivation, - title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, - author={Owren, Brynjulf and Zennaro, Marino}, - journal={SIAM journal on scientific and statistical computing}, - volume={13}, - number={6}, - pages={1488--1501}, - year={1992}, - publisher={SIAM} - }") -Base.@kwdef struct OwrenZen4{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function OwrenZen4(stage_limiter!, step_limiter! = trivial_limiter!) - OwrenZen4(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Owren-Zennaro optimized interpolation 5/4 method (free 5th order interpolant).", - "OwrenZen5", - references = "@article{owren1992derivation, - title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, - author={Owren, Brynjulf and Zennaro, Marino}, - journal={SIAM journal on scientific and statistical computing}, - volume={13}, - number={6}, - pages={1488--1501}, - year={1992}, - publisher={SIAM} - }") -Base.@kwdef struct OwrenZen5{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function OwrenZen5(stage_limiter!, step_limiter! = trivial_limiter!) - OwrenZen5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "A third-order, four-stage explicit FSAL Runge-Kutta method with embedded error -estimator of Bogacki and Shampine.", - "BS3", - references = "@article{bogacki19893, - title={A 3 (2) pair of Runge-Kutta formulas}, - author={Bogacki, Przemyslaw and Shampine, Lawrence F}, - journal={Applied Mathematics Letters}, - volume={2}, - number={4}, - pages={321--325}, - year={1989}, - publisher={Elsevier} - }") -Base.@kwdef struct BS3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function BS3(stage_limiter!, step_limiter! = trivial_limiter!) - BS3(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Dormand-Prince's 5/4 Runge-Kutta method. (free 4th order interpolant).", - "DP5", - references = "@article{dormand1980family, - title={A family of embedded Runge-Kutta formulae}, - author={Dormand, John R and Prince, Peter J}, - journal={Journal of computational and applied mathematics}, - volume={6}, - number={1}, - pages={19--26}, - year={1980}, - publisher={Elsevier} - }") -Base.@kwdef struct DP5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function DP5(stage_limiter!, step_limiter! = trivial_limiter!) - DP5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "A fifth-order explicit Runge-Kutta method with embedded error -estimator of Tsitouras. Free 4th order interpolant.", "Tsit5", - references = "@article{tsitouras2011runge, - title={Runge--Kutta pairs of order 5 (4) satisfying only the first column simplifying assumption}, - author={Tsitouras, Ch}, - journal={Computers \\& Mathematics with Applications}, - volume={62}, - number={2}, - pages={770--775}, - year={2011}, - publisher={Elsevier} - }") -Base.@kwdef struct Tsit5{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -TruncatedStacktraces.@truncate_stacktrace Tsit5 3 -# for backwards compatibility -function Tsit5(stage_limiter!, step_limiter! = trivial_limiter!) - Tsit5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Hairer's 8/5/3 adaption of the Dormand-Prince Runge-Kutta method. (7th order interpolant).", - "DP8", - references = "E. Hairer, S.P. Norsett, G. Wanner, (1993) Solving Ordinary Differential Equations I. - Nonstiff Problems. 2nd Edition. Springer Series in Computational Mathematics, - Springer-Verlag.") -Base.@kwdef struct DP8{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function DP8(stage_limiter!, step_limiter! = trivial_limiter!) - DP8(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Tanaka-Yamashita 7 Runge-Kutta method. (7th order interpolant).", - "TanYam7", - references = "Tanaka M., Muramatsu S., Yamashita S., (1992), On the Optimization of Some Nine-Stage - Seventh-order Runge-Kutta Method, Information Processing Society of Japan, - 33 (12), pp. 1512-1526.") -Base.@kwdef struct TanYam7{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function TanYam7(stage_limiter!, step_limiter! = trivial_limiter!) - TanYam7(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("Tsitouras-Papakostas 8/7 Runge-Kutta method.", "TsitPap8") -Base.@kwdef struct TsitPap8{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function TsitPap8(stage_limiter!, step_limiter! = trivial_limiter!) - TsitPap8(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("Zero Dissipation Runge-Kutta of 6th order.", "FRK65", - extra_keyword_description = """- `omega`: a periodicity phase estimate, - when accurate this method results in zero numerical dissipation. - """, - extra_keyword_default = "omega = 0.0") -Base.@kwdef struct FRK65{StageLimiter, StepLimiter, Thread, T} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - omega::T = 0.0 -end - -# for backwards compatibility -function FRK65(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) - FRK65(stage_limiter!, step_limiter!, False(), omega) -end - -@doc explicit_rk_docstring("Phase-fitted Runge-Kutta of 8th order.", "PFRK87", - extra_keyword_description = """- `omega`: a periodicity phase estimate, - when accurate this method results in zero numerical dissipation. - """, - extra_keyword_default = "omega = 0.0") -Base.@kwdef struct PFRK87{StageLimiter, StepLimiter, Thread, T} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - omega::T = 0.0 -end -# for backwards compatibility -function PFRK87(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) - PFRK87(stage_limiter!, step_limiter!, False(), omega) -end - -@doc explicit_rk_docstring( - "Bogacki-Shampine 5/4 Runge-Kutta method. (lazy 5th order interpolant).", - "BS5", - references = "@article{bogacki1996efficient, - title={An efficient runge-kutta (4, 5) pair}, - author={Bogacki, P and Shampine, Lawrence F}, - journal={Computers \\& Mathematics with Applications}, - volume={32}, - number={6}, - pages={15--28}, - year={1996}, - publisher={Elsevier} - }", - extra_keyword_description = """- `lazy`: determines if the lazy interpolant is used. - """, - extra_keyword_default = "lazy = true") -Base.@kwdef struct BS5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - lazy::Bool = true -end -# for backwards compatibility -function BS5(stage_limiter!, step_limiter! = trivial_limiter!; lazy = true) - BS5(stage_limiter!, step_limiter!, False(), lazy) -end - """ Euler - The canonical forward Euler method. Fixed timestep only. """ -struct Euler <: OrdinaryDiffEqAlgorithm end """ KuttaPRK2p5: Parallel Explicit Runge-Kutta Method diff --git a/src/caches/basic_caches.jl b/src/caches/basic_caches.jl index b5dd5edb7a..45f7564cb6 100644 --- a/src/caches/basic_caches.jl +++ b/src/caches/basic_caches.jl @@ -100,90 +100,5 @@ end alg_cache(alg::OrdinaryDiffEqAlgorithm, prob, callback::F) where {F} = ODEEmptyCache() -@cache struct FunctionMapCache{uType, rateType} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::rateType -end - -function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - FunctionMapCache(u, uprev, - FunctionMap_scale_by_time(alg) ? rate_prototype : - (eltype(u) <: Enum ? copy(u) : zero(u))) -end - -struct FunctionMapConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - FunctionMapConstantCache() -end - -@cache struct ExplicitRKCache{uType, rateType, uNoUnitsType, TabType} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - utilde::rateType - atmp::uNoUnitsType - fsalfirst::rateType - fsallast::rateType - kk::Vector{rateType} - tab::TabType -end - -TruncatedStacktraces.@truncate_stacktrace ExplicitRKCache 1 - -function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - kk = Vector{typeof(rate_prototype)}(undef, 0) - for i in 1:(alg.tableau.stages) - push!(kk, zero(rate_prototype)) - end - fsalfirst = kk[1] - if isfsal(alg.tableau) - fsallast = kk[end] - else - fsallast = zero(rate_prototype) - end - utilde = zero(rate_prototype) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tab = ExplicitRKConstantCache(alg.tableau, rate_prototype) - ExplicitRKCache(u, uprev, tmp, utilde, atmp, fsalfirst, fsallast, kk, tab) -end - -struct ExplicitRKConstantCache{MType, VType, KType} <: OrdinaryDiffEqConstantCache - A::MType - c::VType - α::VType - αEEst::VType - stages::Int - kk::KType -end - -function ExplicitRKConstantCache(tableau, rate_prototype) - @unpack A, c, α, αEEst, stages = tableau - A = copy(A') # Transpose A to column major looping - kk = Array{typeof(rate_prototype)}(undef, stages) # Not ks since that's for integrator.opts.dense - αEEst = isempty(αEEst) ? αEEst : α .- αEEst - ExplicitRKConstantCache(A, c, α, αEEst, stages, kk) -end - -function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - ExplicitRKConstantCache(alg.tableau, rate_prototype) -end - get_chunksize(cache::DiffEqBase.DECache) = error("This cache does not have a chunksize.") -get_chunksize(cache::ODEChunkCache{CS}) where {CS} = CS +get_chunksize(cache::ODEChunkCache{CS}) where {CS} = CS \ No newline at end of file diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index 416a6ea99d..97c74f9cf1 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -393,32 +393,6 @@ end struct PredictiveController <: AbstractController end -@inline function stepsize_controller!(integrator, controller::PredictiveController, alg) - @unpack qmin, qmax, gamma = integrator.opts - EEst = DiffEqBase.value(integrator.EEst) - - if iszero(EEst) - q = inv(qmax) - else - if fac_default_gamma(alg) - fac = gamma - else - if alg isa Union{RadauIIA3, RadauIIA5} - @unpack iter = integrator.cache - @unpack maxiters = alg - else - @unpack iter, maxiters = integrator.cache.nlsolver - end - fac = min(gamma, (1 + 2 * maxiters) * gamma / (iter + 2 * maxiters)) - end - expo = 1 / (get_current_adaptive_order(alg, integrator.cache) + 1) - qtmp = DiffEqBase.fastpow(EEst, expo) / fac - @fastmath q = DiffEqBase.value(max(inv(qmax), min(inv(qmin), qtmp))) - integrator.qold = q - end - q -end - function step_accept_controller!(integrator, controller::PredictiveController, alg, q) @unpack qmin, qmax, gamma, qsteady_min, qsteady_max = integrator.opts EEst = DiffEqBase.value(integrator.EEst) diff --git a/src/integrators/integrator_interface.jl b/src/integrators/integrator_interface.jl index 5f912ff7ee..3a14aa13bf 100644 --- a/src/integrators/integrator_interface.jl +++ b/src/integrators/integrator_interface.jl @@ -104,10 +104,6 @@ end cache::OrdinaryDiffEqMutableCache) (cache.tmp,) end -@inline function DiffEqBase.get_tmp_cache(integrator, alg::Union{RadauIIA3, RadauIIA5}, - cache::OrdinaryDiffEqMutableCache) - (cache.tmp, cache.atmp) -end @inline function DiffEqBase.get_tmp_cache(integrator, alg::OrdinaryDiffEqNewtonAdaptiveAlgorithm, cache::OrdinaryDiffEqMutableCache) diff --git a/src/interp_func.jl b/src/interp_func.jl index 4e31fe0efa..8cc95ac156 100644 --- a/src/interp_func.jl +++ b/src/interp_func.jl @@ -30,58 +30,6 @@ function DiffEqBase.interp_summary(interp::OrdinaryDiffEqInterpolation{ } DiffEqBase.interp_summary(cacheType, interp.dense) end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where {cacheType <: - FunctionMapConstantCache} - "left-endpoint piecewise constant" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where {cacheType <: FunctionMapCache} - "left-endpoint piecewise constant" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{DP5ConstantCache, DP5Cache}} - dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: Union{OwrenZen3Cache, - OwrenZen3ConstantCache}} - dense ? "specialized 3rd order \"free\" interpolation" : "1st order linear" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: Union{OwrenZen4Cache, - OwrenZen4ConstantCache}} - dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: Union{OwrenZen5Cache, - OwrenZen5ConstantCache}} - dense ? "specialized 5th order \"free\" interpolation" : "1st order linear" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Tsit5Cache, Tsit5ConstantCache -}} - dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{BS5ConstantCache, BS5Cache}} - dense ? "specialized 5th order lazy interpolation" : "1st order linear" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{DP8ConstantCache, DP8Cache}} - dense ? "specialized 7th order interpolation" : "1st order linear" -end function DiffEqBase.interp_summary(::Type{cacheType}, dense::Bool) where {cacheType} dense ? "3rd order Hermite" : "1st order linear" end diff --git a/src/perform_step/explicit_rk_perform_step.jl b/src/perform_step/explicit_rk_perform_step.jl index 08ddee112a..e69de29bb2 100644 --- a/src/perform_step/explicit_rk_perform_step.jl +++ b/src/perform_step/explicit_rk_perform_step.jl @@ -1,240 +0,0 @@ -function initialize!(integrator, cache::ExplicitRKConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::ExplicitRKConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - alg = unwrap_alg(integrator, false) - @unpack A, c, α, αEEst, stages = cache - @unpack kk = cache - - # Calc First - kk[1] = integrator.fsalfirst - - # Calc Middle - for i in 2:(stages - 1) - utilde = zero(kk[1]) - for j in 1:(i - 1) - utilde = utilde + A[j, i] * kk[j] - end - kk[i] = f(uprev + dt * utilde, p, t + c[i] * dt) - integrator.stats.nf += 1 - end - - #Calc Last - utilde_last = zero(kk[1]) - for j in 1:(stages - 1) - utilde_last = utilde_last + A[j, end] * kk[j] - end - u_beforefinal = uprev + dt * utilde_last - kk[end] = f(u_beforefinal, p, t + c[end] * dt) - integrator.stats.nf += 1 - integrator.fsallast = kk[end] # Uses fsallast as temp even if not fsal - - # Accumulate Result - accum = α[1] * kk[1] - for i in 2:stages - accum = accum + α[i] * kk[i] - end - u = uprev + dt * accum - - if integrator.alg isa CompositeAlgorithm - # Hairer II, page 22 modified to use Inf norm - n = maximum(abs.((kk[end] .- kk[end - 1]) / (u .- u_beforefinal))) - integrator.eigen_est = integrator.opts.internalnorm(n, t) - end - - if integrator.opts.adaptive - utilde = αEEst[1] .* kk[1] - for i in 2:stages - utilde = utilde + αEEst[i] * kk[i] - end - atmp = calculate_residuals(dt * utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if !isfsal(alg.tableau) - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - end - - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::ExplicitRKCache) - integrator.kshortsize = 2 - integrator.fsallast = cache.fsallast - integrator.fsalfirst = cache.kk[1] - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@generated function accumulate_explicit_stages!(out, A, uprev, kk, dt, ::Val{s}, - ::Val{r} = Val(s)) where {s, r} - if s == 1 - return :(@muladd @.. broadcast=false out=uprev + dt * kk[1]) - elseif s == 2 - # Note that `A` is transposed - return :(@muladd @.. broadcast=false out=uprev + dt * (A[1, $r] * kk[1])) - else - expr = :(@muladd @.. broadcast=false out=uprev + - dt * (A[1, $r] * kk[1] + A[2, $r] * kk[2])) - acc = expr.args[end].args[end].args[end].args[end].args[end].args - for i in 3:(s - 1) - push!(acc, :(A[$i, $r] * kk[$i])) - end - return expr - end -end - -@generated function accumulate_EEst!(out, αEEst, kk, dt, ::Val{s}) where {s} - if s == 1 - return :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1])) - else - expr = :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1] + αEEst[2] * kk[2])) - acc = expr.args[end].args[end].args[end].args[end].args - for i in 3:s - push!(acc, :(αEEst[$i] * kk[$i])) - end - return expr - end -end - -function accumulate_EEst!(out, αEEst, utilde, kk, dt, stages) - @.. broadcast=false utilde=αEEst[1] * kk[1] - for i in 2:stages - @.. broadcast=false utilde=utilde + αEEst[i] * kk[i] - end - @.. broadcast=false out=dt * utilde -end - -@muladd function compute_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, - stages::Integer) where {F} - # Middle - for i in 2:(stages - 1) - @.. broadcast=false utilde=zero(kk[1][1]) - for j in 1:(i - 1) - @.. broadcast=false utilde=utilde + A[j, i] * kk[j] - end - @.. broadcast=false tmp=uprev + dt * utilde - f(kk[i], tmp, p, t + c[i] * dt) - end - - #Last - @.. broadcast=false utilde=zero(kk[1][1]) - for j in 1:(stages - 1) - @.. broadcast=false utilde=utilde + A[j, end] * kk[j] - end - @.. broadcast=false u=uprev + dt * utilde - f(kk[end], u, p, t + c[end] * dt) #fsallast is tmp even if not fsal - return nothing -end - -@generated function compute_stages!(f::F, A, c, u, tmp, uprev, kk, p, t, dt, - ::Val{s}) where {F, s} - quote - Base.@nexprs $(s - 2) i′->begin - i = i′ + 1 - accumulate_explicit_stages!(tmp, A, uprev, kk, dt, Val(i)) - f(kk[i], tmp, p, t + c[i] * dt) - end - accumulate_explicit_stages!(u, A, uprev, kk, dt, Val(s)) - f(kk[s], u, p, t + c[end] * dt) - end -end - -function runtime_split_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, - stages::Integer) where {F} - Base.@nif 17 (s->(s == stages)) (s->compute_stages!(f, A, c, u, tmp, uprev, kk, p, t, - dt, Val(s))) (s->compute_stages!(f, - A, - c, - utilde, - u, - tmp, - uprev, - kk, - p, - t, - dt, - stages)) -end - -function accumulate_fsal!(u, α, utilde, uprev, kk, dt, stages) - @.. broadcast=false utilde=α[1] * kk[1] - for i in 2:stages - @.. broadcast=false utilde=utilde + α[i] * kk[i] - end - @.. broadcast=false u=uprev + dt * utilde -end - -function runtime_split_fsal!(out, A, utilde, uprev, kk, dt, stages) - Base.@nif 17 (s->(s == stages)) (s->accumulate_explicit_stages!(out, A, uprev, kk, dt, - Val(s + 1), Val(1))) (s->accumulate_fsal!(out, - A, - utilde, - uprev, - kk, - dt, - stages)) -end - -function runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) - Base.@nif 17 (s->(s == stages)) (s->accumulate_EEst!(tmp, αEEst, kk, dt, Val(s))) (s->accumulate_EEst!( - tmp, - αEEst, - utilde, - kk, - dt, - stages)) -end - -@muladd function perform_step!(integrator, cache::ExplicitRKCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - alg = unwrap_alg(integrator, false) - # αEEst is `α - αEEst` - @unpack A, c, α, αEEst, stages = cache.tab - @unpack kk, utilde, tmp, atmp = cache - - runtime_split_stages!(f, A, c, utilde, u, tmp, uprev, kk, p, t, dt, stages) - integrator.stats.nf += stages - 1 - - #Accumulate - if !isfsal(alg.tableau) - runtime_split_fsal!(u, α, utilde, uprev, kk, dt, stages) - end - - if integrator.alg isa CompositeAlgorithm - # Hairer II, page 22 modified to use Inf norm - @.. broadcast=false utilde=abs((kk[end] - kk[end - 1]) / (u - tmp)) - integrator.eigen_est = integrator.opts.internalnorm(norm(utilde, Inf), t) - end - - if integrator.opts.adaptive - runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) - calculate_residuals!(atmp, tmp, uprev, u, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if !isfsal(alg.tableau) - f(integrator.fsallast, u, p, t + dt) - integrator.stats.nf += 1 - end -end diff --git a/src/perform_step/fixed_timestep_perform_step.jl b/src/perform_step/fixed_timestep_perform_step.jl index 643ce748f8..2923459c72 100644 --- a/src/perform_step/fixed_timestep_perform_step.jl +++ b/src/perform_step/fixed_timestep_perform_step.jl @@ -40,492 +40,4 @@ function perform_step!(integrator, cache::FunctionMapCache, repeat_step = false) end integrator.stats.nf += 1 end -end - -function initialize!(integrator, cache::EulerConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::EulerConstantCache, repeat_step = false) - @unpack t, dt, uprev, f, p = integrator - @muladd u = @.. broadcast=false uprev+dt * integrator.fsalfirst - k = f(u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 - integrator.fsallast = k - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::EulerCache) - integrator.kshortsize = 2 - @unpack k, fsalfirst = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::EulerCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @muladd @.. broadcast=false u=uprev + dt * integrator.fsalfirst - f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function initialize!(integrator, cache::Union{HeunConstantCache, RalstonConstantCache}) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, - cache::Union{HeunConstantCache, RalstonConstantCache}, - repeat_step = false) - @unpack t, dt, uprev, u, f, p, fsalfirst = integrator - - # precalculations - if cache isa HeunConstantCache - a₁ = dt - a₂ = dt / 2 - else # Ralston - a₁ = 2 * dt / 3 - a₂ = dt / 4 - a₃ = 3 * a₂ - end - - tmp = @.. broadcast=false uprev+a₁ * fsalfirst - k2 = f(tmp, p, t + a₁) - integrator.stats.nf += 1 - - if cache isa HeunConstantCache - u = @.. broadcast=false uprev+a₂ * (fsalfirst + k2) - else - u = @.. broadcast=false uprev+a₂*fsalfirst+a₃*k2 - end - - if integrator.opts.adaptive - if cache isa HeunConstantCache - tmp = @.. broadcast=false a₂*(k2 - fsalfirst) - else - tmp = @.. broadcast=false a₃*(k2 - fsalfirst) - end - - atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - k = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.fsallast = k - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::Union{HeunCache, RalstonCache}) - integrator.kshortsize = 2 - @unpack k, fsalfirst = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::Union{HeunCache, RalstonCache}, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack fsalfirst, k, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - - # precalculations - if cache isa HeunCache - a₁ = dt - a₂ = dt / 2 - else # Ralston - a₁ = 2 * dt / 3 - a₂ = dt / 4 - a₃ = 3 * a₂ - end - - @.. broadcast=false thread=thread tmp=uprev + a₁ * fsalfirst - stage_limiter!(tmp, integrator, p, t + a₁) - f(k, tmp, p, t + a₁) - integrator.stats.nf += 1 - - if cache isa HeunCache - @.. broadcast=false thread=thread u=uprev + a₂ * (fsalfirst + k) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - else - @.. broadcast=false thread=thread u=uprev + a₂ * fsalfirst + a₃ * k - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - end - - if integrator.opts.adaptive - if cache isa HeunCache - @.. broadcast=false thread=thread tmp=a₂ * (k - fsalfirst) - else - @.. broadcast=false thread=thread tmp=a₃ * (k - fsalfirst) - end - - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function initialize!(integrator, cache::MidpointConstantCache) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::MidpointConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - halfdt = dt / 2 - tmp = @.. broadcast=false uprev+halfdt * integrator.fsalfirst - k = f(tmp, p, t + halfdt) - integrator.stats.nf += 1 - u = @.. broadcast=false uprev+dt * k - integrator.fsallast = f(u, p, t + dt) # For interpolation, then FSAL'd - integrator.stats.nf += 1 - if integrator.opts.adaptive - utilde = @.. broadcast=false dt*(integrator.fsalfirst - k) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::MidpointCache) - @unpack k, fsalfirst = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # FSAL for interpolation - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::MidpointCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, k, fsalfirst, atmp, stage_limiter!, step_limiter!, thread = cache - halfdt = dt / 2 - @.. broadcast=false thread=thread tmp=uprev + halfdt * fsalfirst - stage_limiter!(k, tmp, p, t + halfdt) - f(k, tmp, p, t + halfdt) - integrator.stats.nf += 1 - @.. broadcast=false thread=thread u=uprev + dt * k - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - if integrator.opts.adaptive - @.. broadcast=false thread=thread tmp=dt * (fsalfirst - k) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - f(k, u, p, t + dt) - integrator.stats.nf += 1 -end - -function initialize!(integrator, cache::RK4ConstantCache) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::RK4ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - halfdt = dt / 2 - k₁ = integrator.fsalfirst - ttmp = t + halfdt - k₂ = f(uprev + halfdt * k₁, p, ttmp) - k₃ = f(uprev + halfdt * k₂, p, ttmp) - k₄ = f(uprev + dt * k₃, p, t + dt) - u = uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 4 - if integrator.opts.adaptive - # Shampine Solving ODEs and DDEs with Residual Control Estimate - k₅ = integrator.fsallast - - # one(t) so that types are correct but unitless - σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 - σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 - p1 = (1 - σ₁) * uprev + σ₁ * u + - σ₁ * (σ₁ - 1) * ((1 - 2σ₁) * (u - uprev) + (σ₁ - 1) * dt * k₁ + σ₁ * dt * k₅) - p2 = (1 - σ₂) * uprev + σ₂ * u + - σ₂ * (σ₂ - 1) * ((1 - 2σ₂) * (u - uprev) + (σ₂ - 1) * dt * k₁ + σ₂ * dt * k₅) - pprime1 = k₁ + - σ₁ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₁ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt - pprime2 = k₁ + - σ₂ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₂ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt - e1 = integrator.opts.internalnorm( - calculate_residuals(dt * (f(p1, p, t + σ₁ * dt) - - pprime1), uprev, u, - integrator.opts.abstol, - integrator.opts.reltol, - integrator.opts.internalnorm, - t), - t) - e2 = integrator.opts.internalnorm( - calculate_residuals(dt * (f(p2, p, t + σ₂ * dt) - - pprime2), uprev, u, - integrator.opts.abstol, - integrator.opts.reltol, - integrator.opts.internalnorm, - t), - t) - integrator.stats.nf += 2 - integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) - end - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::RK4Cache) - @unpack tmp, fsalfirst, k₂, k₃, k₄, k = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # pre-start FSAL - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::RK4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k₂, k₃, k₄, k, atmp, stage_limiter!, step_limiter!, thread = cache - k₁ = fsalfirst - halfdt = dt / 2 - ttmp = t + halfdt - @.. broadcast=false thread=thread tmp=uprev + halfdt * k₁ - stage_limiter!(tmp, integrator, p, ttmp) - f(k₂, tmp, p, ttmp) - @.. broadcast=false thread=thread tmp=uprev + halfdt * k₂ - stage_limiter!(tmp, integrator, p, ttmp) - f(k₃, tmp, p, ttmp) - @.. broadcast=false thread=thread tmp=uprev + dt * k₃ - stage_limiter!(tmp, integrator, p, t + dt) - f(k₄, tmp, p, t + dt) - @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k, u, p, t + dt) - integrator.stats.nf += 4 - if integrator.opts.adaptive - # Shampine Solving ODEs and DDEs with Residual Control Estimate - k₅ = k - _p = k₂ - pprime = k₃ # Alias some cache arrays - # one(t) so that types are correct but unitless - σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 - σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 - @.. broadcast=false thread=thread tmp=(1 - σ₁) * uprev + σ₁ * u + - σ₁ * (σ₁ - 1) * - ((1 - 2σ₁) * (u - uprev) + - (σ₁ - 1) * dt * k₁ + - σ₁ * dt * k₅) - @.. broadcast=false thread=thread pprime=k₁ + - σ₁ * - (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₁ * - (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - - 6 * u) + - 6 * u) / dt - f(_p, tmp, p, t + σ₁ * dt) - @.. broadcast=false thread=thread tmp=dt * (_p - pprime) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - e1 = integrator.opts.internalnorm(atmp, t) - @.. broadcast=false thread=thread tmp=(1 - σ₂) * uprev + σ₂ * u + - σ₂ * (σ₂ - 1) * - ((1 - 2σ₂) * (u - uprev) + - (σ₂ - 1) * dt * k₁ + - σ₂ * dt * k₅) - @.. broadcast=false thread=thread pprime=k₁ + - σ₂ * - (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₂ * - (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - - 6 * u) + - 6 * u) / dt - f(_p, tmp, p, t + σ₂ * dt) - @.. broadcast=false thread=thread tmp=dt * (_p - pprime) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - e2 = integrator.opts.internalnorm(atmp, t) - integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) - integrator.stats.nf += 2 - end -end - -function initialize!(integrator, cache::Anas5ConstantCache) - integrator.kshortsize = 7 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::Anas5ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache - ## Note that c1 and b2 were 0. - alg = unwrap_alg(integrator, false) - w = alg.w - v = w * dt - ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. - a65 = (-8000 // 1071) * - (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + - 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) - a61 += (-119 // 200) * a65 - a63 += (189 // 100) * a65 - a64 += (-459 // 200) * a65 - k1 = integrator.fsalfirst - k2 = f(uprev + dt * a21 * k1, p, t + c2 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c3 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + 2 * k3), p, t + c4 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c5 * dt) - k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, - t + c6 * dt) - u = uprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) - k7 = f(u, p, t + dt) - integrator.fsallast = k7 - integrator.stats.nf += 6 - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.u = u -end - -function initialize!(integrator, cache::Anas5Cache) - integrator.kshortsize = 7 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k7 # setup pointers - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::Anas5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - uidx = eachindex(integrator.uprev) - @unpack k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache.tab - alg = unwrap_alg(integrator, false) - w = alg.w - v = w * dt - ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. - a65 = (-8000 // 1071) * - (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + - 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) - a61 += (-119 // 200) * a65 - a63 += (189 // 100) * a65 - a64 += (-459 // 200) * a65 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + a21 * k1[i] - end - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + dt * (a31 * k1[i] + a32 * k2[i]) - end - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + dt * (a41 * k1[i] + a42 * k2[i] + 2 * k3[i]) - end - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + - dt * (a51 * k1[i] + a52 * k2[i] + a53 * k3[i] + a54 * k4[i]) - end - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + - dt * (a61 * k1[i] + a62 * k2[i] + a63 * k3[i] + a64 * k4[i] + - a65 * k5[i]) - end - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @tight_loop_macros for i in uidx - @inbounds u[i] = uprev[i] + - dt * - (b1 * k1[i] + b3 * k3[i] + b4 * k4[i] + b5 * k5[i] + b6 * k6[i]) - end - stage_limiter!(tmp, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k7, u, p, t + dt) - integrator.stats.nf += 6 -end +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 081f686c17..4825163319 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -83,6 +83,42 @@ function activate_rosenbrock() Pkg.instantiate() end +function activate_firk() + Pkg.activate("../lib/OrdinaryDiffEqFIRK") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + +function activate_sdirk() + Pkg.activate("../lib/OrdinaryDiffEqSDIRK") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + +function activate_explicit_rk() + Pkg.activate("../lib/OrdinaryDiffEqExplicitRK") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + +function activate_bdf() + Pkg.activate("../lib/OrdinaryDiffEqBDF") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + +function low_order_rk() + Pkg.activate("../lib/OrdinaryDiffEqLowOrderRK") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + +function high_order_rk() + Pkg.activate("../lib/OrdinaryDiffEqHighOrderRK") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + #Start Test Script @time begin @@ -206,19 +242,23 @@ end end if !is_APPVEYOR && GROUP == "AlgConvergence_II" - @time @safetestset "OwrenZen Tests" include("algconvergence/owrenzen_tests.jl") + @time @safetestset "OwrenZen Tests" include("../lib/OrdinaryLowOrderRK/test/owrenzen_tests.jl") @time @safetestset "Runge-Kutta-Chebyshev Tests" include("../lib/OrdinaryDiffEqStabilizedRK/test/rkc_tests.jl") end if !is_APPVEYOR && GROUP == "AlgConvergence_III" @time @safetestset "Linear Methods Tests" include("algconvergence/linear_method_tests.jl") @time @safetestset "Split Methods Tests" include("algconvergence/split_methods_tests.jl") - @time @safetestset "FIRK Tests" include("algconvergence/ode_firk_tests.jl") @time @safetestset "Linear-Nonlinear Methods Tests" include("algconvergence/linear_nonlinear_convergence_tests.jl") @time @safetestset "Linear-Nonlinear Krylov Methods Tests" include("algconvergence/linear_nonlinear_krylov_tests.jl") @time @safetestset "Quadruple precision Runge-Kutta Tests" include("algconvergence/ode_quadruple_precision_tests.jl") end + if !is_APPVEYOR && GROUP == "FIRK" + @time @safetestset "FIRK Tests" include("../lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl") + end + + if !is_APPVEYOR && GROUP == "Rosenbrock" @time @safetestset "Rosenbrock Tests" include("../lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl") end From 00ad2d21af1afce399d1bee809697ce43af01d2f Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 15:13:31 +0530 Subject: [PATCH 012/112] Changes --- lib/OrdinaryDiffEqBDF/Project.toml | 1 + .../src/OrdinaryDiffEqBDF.jl | 22 +++++++++++++++++-- lib/OrdinaryDiffEqExplicitRK/Project.toml | 20 +++++++++++++++++ .../src/OrdinaryDiffEqExplicitRK.jl | 21 ++++++++++++++++-- .../test/runtests.jl | 2 +- lib/OrdinaryDiffEqFIRK/Project.toml | 22 ++++++++++++++++++- .../src/OrdinaryDiffEqFIRK.jl | 22 ++++++++++++++++++- lib/OrdinaryDiffEqFIRK/test/runtests.jl | 3 +++ lib/OrdinaryDiffEqSDIRK/Project.toml | 20 +++++++++++++++++ .../src/OrdinaryDiffEqSDIRK.jl | 5 +---- lib/OrdinaryHighOrderRK/Project.toml | 20 +++++++++++++++++ lib/OrdinaryLowOrderRK/Project.toml | 20 +++++++++++++++++ src/algorithms.jl | 2 +- 13 files changed, 168 insertions(+), 12 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml index 526d7700ce..839ad7abe6 100644 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -2,3 +2,4 @@ name = "OrdinaryDiffEqBDF" uuid = "34d55129-80d4-4dd1-bb14-71372a5ab94f" authors = ["ParamThakkar123 "] version = "1.0.0" + diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 627af4524d..aecf972641 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -1,5 +1,23 @@ module OrdinaryDiffEqBDF -greet() = print("Hello World!") +import OrdinaryDiffEq: alg_order, calculate_residuals!, + initialize!, perform_step!, @unpack, unwrap_alg, + calculate_residuals, alg_extrapolates, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqAdaptivePartitionedAlgorithm, + OrdinaryDiffEqPartitionedAlgorithm, + OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, + alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, + trivial_limiter!, _ode_interpolant!, _ode_addsteps! +using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools +using DiffEqBase: @def, @tight_loop_macros -end # module OrdinaryDiffEqBDF + +include("algorithms.jl") +include("alg_utils.jl") +include("bdf_caches.jl") +include("bdf_perform_step.jl") + +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/Project.toml b/lib/OrdinaryDiffEqExplicitRK/Project.toml index 899f18dcc8..fd4223b529 100644 --- a/lib/OrdinaryDiffEqExplicitRK/Project.toml +++ b/lib/OrdinaryDiffEqExplicitRK/Project.toml @@ -2,3 +2,23 @@ name = "OrdinaryDiffEqExplicitRK" uuid = "a6f9a3f1-1c5b-4457-b8d8-bad5275751bf" authors = ["ParamThakkar123 "] version = "0.1.0" + +[deps] +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + +[compat] +julia = "1.10" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl b/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl index 9b460a52bd..8e04177dc8 100644 --- a/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl +++ b/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl @@ -1,5 +1,22 @@ module OrdinaryDiffEqExplicitRK -greet() = print("Hello World!") +import OrdinaryDiffEq: alg_order, calculate_residuals!, + initialize!, perform_step!, @unpack, unwrap_alg, + calculate_residuals, alg_extrapolates, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqAdaptivePartitionedAlgorithm, + OrdinaryDiffEqPartitionedAlgorithm, + OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, + alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, + trivial_limiter!, _ode_interpolant!, _ode_addsteps! +using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools +using DiffEqBase: @def, @tight_loop_macros -end # module OrdinaryDiffEqExplicitRK +include("algorithms.jl") +include("alg_utils.jl") +include("explicit_rk_caches.jl") +include("explicit_rk_perform_step.jl") + +end diff --git a/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl b/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl index 738c8013cc..4aee75dc86 100644 --- a/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl +++ b/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl @@ -1,3 +1,3 @@ using SafeTestsets -@time @safetestset "Extrapolation Tests" include("ode_extrapolation_tests.jl") +@time @safetestset "Extrapolation Tests" include("ode_extrapolation_tests.jl") \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/Project.toml b/lib/OrdinaryDiffEqFIRK/Project.toml index 0b8a6bc963..062380e37b 100644 --- a/lib/OrdinaryDiffEqFIRK/Project.toml +++ b/lib/OrdinaryDiffEqFIRK/Project.toml @@ -1,4 +1,24 @@ name = "OrdinaryDiffEqFIRK" uuid = "1072fcc4-aad5-4cac-8081-8f348bae166b" authors = ["ParamThakkar123 "] -version = "0.1.0" +version = "1.0.0" + +[deps] +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + +[compat] +julia = "1.10" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl index 150ae7c5f0..1d8061ebdd 100644 --- a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl +++ b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl @@ -1,5 +1,25 @@ module OrdinaryDiffEqFIRK -greet() = print("Hello World!") +import OrdinaryDiffEq: alg_order, calculate_residuals!, + initialize!, perform_step!, @unpack, unwrap_alg, + calculate_residuals, alg_extrapolates, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqAdaptivePartitionedAlgorithm, + OrdinaryDiffEqPartitionedAlgorithm, + OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, + alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, + trivial_limiter!, _ode_interpolant!, _ode_addsteps! +using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools +using DiffEqBase: @def, @tight_loop_macros + +include("algorithms.jl") +include("alg_utils.jl") +include("controllers.jl") +include("integrator_interface.jl") +include("firk_tableaus.jl") +include("firk_caches.jl") +include("firk_perform_step.jl") end diff --git a/lib/OrdinaryDiffEqFIRK/test/runtests.jl b/lib/OrdinaryDiffEqFIRK/test/runtests.jl index e69de29bb2..e4e127fb44 100644 --- a/lib/OrdinaryDiffEqFIRK/test/runtests.jl +++ b/lib/OrdinaryDiffEqFIRK/test/runtests.jl @@ -0,0 +1,3 @@ +using SafeTestsets + +@time @safetestset "Extrapolation Tests" include("ode_firk_tests.jl") \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 76bfd6e5be..4f77afdd3a 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -2,3 +2,23 @@ name = "OrdinaryDiffEqSDIRK" uuid = "b2cb2727-2d56-444c-bf6a-1484cae16977" authors = ["ParamThakkar123 "] version = "1.0.0" + +[deps] +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + +[compat] +julia = "1.10" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index b378fa6ee4..8272f5a9ae 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -1,5 +1,2 @@ module OrdinaryDiffEqSDIRK - -greet() = print("Hello World!") - -end # module OrdinaryDiffEqSDIRK +end diff --git a/lib/OrdinaryHighOrderRK/Project.toml b/lib/OrdinaryHighOrderRK/Project.toml index fcbd66bf1b..93c8f5c09f 100644 --- a/lib/OrdinaryHighOrderRK/Project.toml +++ b/lib/OrdinaryHighOrderRK/Project.toml @@ -2,3 +2,23 @@ name = "OrdinaryDiffEqHighOrderRK" uuid = "3383601e-94d4-44bc-9605-458335d811d3" authors = ["ParamThakkar123 "] version = "1.0.0" + +[deps] +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + +[compat] +julia = "1.10" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryLowOrderRK/Project.toml b/lib/OrdinaryLowOrderRK/Project.toml index 7cb4ff6beb..1543727349 100644 --- a/lib/OrdinaryLowOrderRK/Project.toml +++ b/lib/OrdinaryLowOrderRK/Project.toml @@ -2,3 +2,23 @@ name = "OrdinaryDiffEqLowOrderRK" uuid = "0e0916b3-e0a4-463e-8dfa-d409d9d724ed" authors = ["ParamThakkar123 "] version = "0.1.0" + +[deps] +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + +[compat] +julia = "1.10" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/src/algorithms.jl b/src/algorithms.jl index 2b1f4226de..28513c9c08 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -608,8 +608,8 @@ function PDIRK44(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{tru end ### Algorithm Groups +#ABDF2 const MultistepAlgorithms = Union{ - ABDF2, AB3, AB4, AB5, ABM32, ABM43, ABM54} const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF, From ffd603f21a1cd1265216115bce84c55b53a788ae Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 15:23:15 +0530 Subject: [PATCH 013/112] Changes --- lib/OrdinaryDiffEqBDF/Project.toml | 17 +++++++++++++++++ lib/OrdinaryDiffEqFIRK/Project.toml | 2 -- lib/OrdinaryDiffEqSDIRK/Project.toml | 2 -- lib/OrdinaryHighOrderRK/Project.toml | 2 -- lib/OrdinaryLowOrderRK/Project.toml | 2 -- src/algorithms.jl | 5 ++--- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml index 839ad7abe6..cd2e47a403 100644 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -3,3 +3,20 @@ uuid = "34d55129-80d4-4dd1-bb14-71372a5ab94f" authors = ["ParamThakkar123 "] version = "1.0.0" +[deps] +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" + +[compat] +julia = "1.10" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/Project.toml b/lib/OrdinaryDiffEqFIRK/Project.toml index 062380e37b..ac178467a2 100644 --- a/lib/OrdinaryDiffEqFIRK/Project.toml +++ b/lib/OrdinaryDiffEqFIRK/Project.toml @@ -8,8 +8,6 @@ FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" -RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 4f77afdd3a..dd466e9602 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -8,8 +8,6 @@ FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" -RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [compat] julia = "1.10" diff --git a/lib/OrdinaryHighOrderRK/Project.toml b/lib/OrdinaryHighOrderRK/Project.toml index 93c8f5c09f..361738eb0b 100644 --- a/lib/OrdinaryHighOrderRK/Project.toml +++ b/lib/OrdinaryHighOrderRK/Project.toml @@ -8,8 +8,6 @@ FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" -RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [compat] julia = "1.10" diff --git a/lib/OrdinaryLowOrderRK/Project.toml b/lib/OrdinaryLowOrderRK/Project.toml index 1543727349..42d0e25784 100644 --- a/lib/OrdinaryLowOrderRK/Project.toml +++ b/lib/OrdinaryLowOrderRK/Project.toml @@ -8,8 +8,6 @@ FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" -RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [compat] julia = "1.10" diff --git a/src/algorithms.jl b/src/algorithms.jl index 28513c9c08..86a2bb481c 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -608,12 +608,11 @@ function PDIRK44(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{tru end ### Algorithm Groups -#ABDF2 +#ABDF2 SBDF SBDF, KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, const MultistepAlgorithms = Union{ AB3, AB4, AB5, ABM32, ABM43, ABM54} -const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF, - KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, CFNLIRK3} +const SplitAlgorithms = Union{CNAB2, CNLF2, CFNLIRK3} #= struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} From a84662f10ad7c964f8258cc20f73163ceb317719 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 15:32:12 +0530 Subject: [PATCH 014/112] Changes --- src/algorithms.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/algorithms.jl b/src/algorithms.jl index 86a2bb481c..c5d60f996a 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -608,11 +608,11 @@ function PDIRK44(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{tru end ### Algorithm Groups -#ABDF2 SBDF SBDF, KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, +#ABDF2 SBDF SBDF, KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, CFNLIRK3 const MultistepAlgorithms = Union{ AB3, AB4, AB5, ABM32, ABM43, ABM54} -const SplitAlgorithms = Union{CNAB2, CNLF2, CFNLIRK3} +const SplitAlgorithms = Union{CNAB2, CNLF2} #= struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} From 410181b7839e8b6689e1ff1bf8b689753afd662d Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 15:49:59 +0530 Subject: [PATCH 015/112] Fixes --- src/alg_utils.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 7ce6406509..0d0b9449b7 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -20,6 +20,8 @@ function SciMLBase.forwarddiffs_model(alg::Union{OrdinaryDiffEqAdaptiveImplicitA alg_autodiff(alg) isa AutoForwardDiff end SciMLBase.forwarddiffs_model_time(alg::RosenbrockAlgorithm) = true +struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end +FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() # isadaptive is defined below. From 41c0c5d239828fc18d2c840c3a56dc334dd4aeb0 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 16:03:16 +0530 Subject: [PATCH 016/112] Fixes --- .../src/OrdinaryDiffEqBDF.jl | 2 ++ .../src/OrdinaryDiffEqFIRK.jl | 2 ++ .../src/OrdinaryHighOrderRK.jl | 26 +++++++++++++-- .../src/OrdinaryLowOrderRK.jl | 32 +++++++++++++++++-- src/alg_utils.jl | 1 + 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index aecf972641..9d4a0e02cd 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -20,4 +20,6 @@ include("alg_utils.jl") include("bdf_caches.jl") include("bdf_perform_step.jl") +export SBDF, ABDF2, QNDF1, QNDF2, QNDF, MEBDF2 + end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl index 1d8061ebdd..12f83f81f7 100644 --- a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl +++ b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl @@ -22,4 +22,6 @@ include("firk_tableaus.jl") include("firk_caches.jl") include("firk_perform_step.jl") +export RadauIIA3, RadauIIA5 + end diff --git a/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl b/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl index d6be00d8f3..2766202ed6 100644 --- a/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl +++ b/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl @@ -1,5 +1,27 @@ module OrdinaryHighOrderRK -greet() = print("Hello World!") +import OrdinaryDiffEq: alg_order, calculate_residuals!, + initialize!, perform_step!, @unpack, unwrap_alg, + calculate_residuals, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqAdaptiveAlgorithm, OrdinaryDiffEqPartitionedAlgorithm, + CompiledFloats, uses_uprev, + alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + constvalue, _unwrap_val, du_alias_or_new, + explicit_rk_docstring, trivial_limiter!, + _ode_interpolant!, _ode_addsteps! +using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools -end # module OrdinaryHighOrderRK +include("algorithms.jl") +include("alg_utils.jl") +include("high_order_rk_caches.jl") +include("interp_func.jl") +include("interpolants.jl") +include("high_order_rk_addsteps.jl") +include("high_order_rk_tableaus.jl") +include("high_order_rk_perform_step.jl") + +export TanYam7, DP8, TsitPap8, PFRK87 + +end diff --git a/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl b/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl index 8739bea899..6e5c7b827f 100644 --- a/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl +++ b/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl @@ -1,5 +1,33 @@ module OrdinaryLowOrderRK -greet() = print("Hello World!") +import OrdinaryDiffEq: alg_order, calculate_residuals!, + initialize!, perform_step!, @unpack, unwrap_alg, + calculate_residuals, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqAdaptiveAlgorithm, OrdinaryDiffEqPartitionedAlgorithm, + CompiledFloats, uses_uprev, + alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + constvalue, _unwrap_val, du_alias_or_new, + explicit_rk_docstring, trivial_limiter!, + _ode_interpolant!, _ode_addsteps! +using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools -end # module OrdinaryLowOrderRK +include("algorithms.jl") +include("alg_utils.jl") +include("low_order_rk_caches.jl") +include("interp_func.jl") +include("interpolants.jl") +include("fixed_timestep_perform_step.jl") +include("low_order_rk_addsteps.jl") +include("low_order_rk_tableaus.jl") +include("low_order_rk_caches.jl") +include("split_perform_step.jl") + +export Heun, Ralston, Midpoint, OwrenZen3, OwrenZen4, + OwrenZen5, RK4, BS3, BS5, Tsit5, DP5, Anas5, RKO65, + FRK65, RKM, MSRK5, MSRK6, PSRK4p7q6, PSRK3p6q5, + Stepanov5, SIR54, Alshina2, Alshina3, Alshina6, Euler, + PSRK3p5q4, SplitEuler + +end \ No newline at end of file diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 0d0b9449b7..41a6a37c42 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -20,6 +20,7 @@ function SciMLBase.forwarddiffs_model(alg::Union{OrdinaryDiffEqAdaptiveImplicitA alg_autodiff(alg) isa AutoForwardDiff end SciMLBase.forwarddiffs_model_time(alg::RosenbrockAlgorithm) = true + struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() From 894882aa88de51706fa0f68428cc05ad81556cc0 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 16:06:00 +0530 Subject: [PATCH 017/112] FunctionMap --- src/alg_utils.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 41a6a37c42..6af9dce0d5 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -1,5 +1,6 @@ ## SciMLBase Trait Definitions +using OrdinaryDiffEq: FunctionMap function SciMLBase.isautodifferentiable(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm, FunctionMap}) true @@ -21,9 +22,6 @@ function SciMLBase.forwarddiffs_model(alg::Union{OrdinaryDiffEqAdaptiveImplicitA end SciMLBase.forwarddiffs_model_time(alg::RosenbrockAlgorithm) = true -struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end -FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() - # isadaptive is defined below. ## OrdinaryDiffEq Internal Traits From 7b79e4e6096e1d645174a86af8a7be6647e939fc Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 17:33:02 +0530 Subject: [PATCH 018/112] FunctionMap --- src/alg_utils.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 6af9dce0d5..b33cebca70 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -1,6 +1,4 @@ ## SciMLBase Trait Definitions - -using OrdinaryDiffEq: FunctionMap function SciMLBase.isautodifferentiable(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm, FunctionMap}) true @@ -22,6 +20,8 @@ function SciMLBase.forwarddiffs_model(alg::Union{OrdinaryDiffEqAdaptiveImplicitA end SciMLBase.forwarddiffs_model_time(alg::RosenbrockAlgorithm) = true +struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end + # isadaptive is defined below. ## OrdinaryDiffEq Internal Traits From 1e45e12b23f53ea3825140c5b7d843c54c05ce5f Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 17:43:01 +0530 Subject: [PATCH 019/112] FunctionMap --- lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl b/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl index 6e5c7b827f..806dfe4dd6 100644 --- a/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl +++ b/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl @@ -24,7 +24,7 @@ include("low_order_rk_tableaus.jl") include("low_order_rk_caches.jl") include("split_perform_step.jl") -export Heun, Ralston, Midpoint, OwrenZen3, OwrenZen4, +export FunctionMap, Heun, Ralston, Midpoint, OwrenZen3, OwrenZen4, OwrenZen5, RK4, BS3, BS5, Tsit5, DP5, Anas5, RKO65, FRK65, RKM, MSRK5, MSRK6, PSRK4p7q6, PSRK3p6q5, Stepanov5, SIR54, Alshina2, Alshina3, Alshina6, Euler, From 5d482f70020a4233aa5fde90dea2863af1930684 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 13 Jul 2024 18:29:35 +0530 Subject: [PATCH 020/112] Fixes --- .../Project.toml | 0 .../src/OrdinaryHighOrderRK.jl | 0 .../src/alg_utils.jl | 0 .../src/algorithms.jl | 0 .../src/high_order_rk_addsteps.jl | 0 .../src/high_order_rk_caches.jl | 0 .../src/high_order_rk_perform_step.jl | 0 .../src/high_order_rk_tableaus.jl | 0 .../src/interp_func.jl | 0 .../src/interpolants.jl | 0 .../Project.toml | 0 .../src/OrdinaryDiffEqLowOrderRK.jl} | 0 .../src/alg_utils.jl | 0 .../src/algorithms.jl | 0 .../src/fixed_timestep_perform_step.jl | 0 .../src/interp_func.jl | 0 .../src/interpolants.jl | 0 .../src/low_order_rk_addsteps.jl | 0 .../src/low_order_rk_caches.jl | 0 .../src/low_order_rk_perform_step.jl | 0 .../src/low_order_rk_tableaus.jl | 0 .../src/split_perform_step.jl | 0 .../test/owrenzen_tests.jl | 0 .../test/runtests.jl | 0 src/OrdinaryDiffEq.jl | 2 +- src/alg_utils.jl | 1 + 26 files changed, 2 insertions(+), 1 deletion(-) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/Project.toml (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/OrdinaryHighOrderRK.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/alg_utils.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/algorithms.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/high_order_rk_addsteps.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/high_order_rk_caches.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/high_order_rk_perform_step.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/high_order_rk_tableaus.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/interp_func.jl (100%) rename lib/{OrdinaryHighOrderRK => OrdinaryDiffEqHighOrderRK}/src/interpolants.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/Project.toml (100%) rename lib/{OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl => OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl} (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/alg_utils.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/algorithms.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/fixed_timestep_perform_step.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/interp_func.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/interpolants.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/low_order_rk_addsteps.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/low_order_rk_caches.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/low_order_rk_perform_step.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/low_order_rk_tableaus.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/src/split_perform_step.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/test/owrenzen_tests.jl (100%) rename lib/{OrdinaryLowOrderRK => OrdinaryDiffEqLowOrderRK}/test/runtests.jl (100%) diff --git a/lib/OrdinaryHighOrderRK/Project.toml b/lib/OrdinaryDiffEqHighOrderRK/Project.toml similarity index 100% rename from lib/OrdinaryHighOrderRK/Project.toml rename to lib/OrdinaryDiffEqHighOrderRK/Project.toml diff --git a/lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl b/lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryHighOrderRK.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/OrdinaryHighOrderRK.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryHighOrderRK.jl diff --git a/lib/OrdinaryHighOrderRK/src/alg_utils.jl b/lib/OrdinaryDiffEqHighOrderRK/src/alg_utils.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/alg_utils.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/alg_utils.jl diff --git a/lib/OrdinaryHighOrderRK/src/algorithms.jl b/lib/OrdinaryDiffEqHighOrderRK/src/algorithms.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/algorithms.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/algorithms.jl diff --git a/lib/OrdinaryHighOrderRK/src/high_order_rk_addsteps.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_addsteps.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/high_order_rk_addsteps.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_addsteps.jl diff --git a/lib/OrdinaryHighOrderRK/src/high_order_rk_caches.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_caches.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/high_order_rk_caches.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_caches.jl diff --git a/lib/OrdinaryHighOrderRK/src/high_order_rk_perform_step.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_perform_step.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/high_order_rk_perform_step.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_perform_step.jl diff --git a/lib/OrdinaryHighOrderRK/src/high_order_rk_tableaus.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_tableaus.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/high_order_rk_tableaus.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_tableaus.jl diff --git a/lib/OrdinaryHighOrderRK/src/interp_func.jl b/lib/OrdinaryDiffEqHighOrderRK/src/interp_func.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/interp_func.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/interp_func.jl diff --git a/lib/OrdinaryHighOrderRK/src/interpolants.jl b/lib/OrdinaryDiffEqHighOrderRK/src/interpolants.jl similarity index 100% rename from lib/OrdinaryHighOrderRK/src/interpolants.jl rename to lib/OrdinaryDiffEqHighOrderRK/src/interpolants.jl diff --git a/lib/OrdinaryLowOrderRK/Project.toml b/lib/OrdinaryDiffEqLowOrderRK/Project.toml similarity index 100% rename from lib/OrdinaryLowOrderRK/Project.toml rename to lib/OrdinaryDiffEqLowOrderRK/Project.toml diff --git a/lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl b/lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/OrdinaryLowOrderRK.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl diff --git a/lib/OrdinaryLowOrderRK/src/alg_utils.jl b/lib/OrdinaryDiffEqLowOrderRK/src/alg_utils.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/alg_utils.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/alg_utils.jl diff --git a/lib/OrdinaryLowOrderRK/src/algorithms.jl b/lib/OrdinaryDiffEqLowOrderRK/src/algorithms.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/algorithms.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/algorithms.jl diff --git a/lib/OrdinaryLowOrderRK/src/fixed_timestep_perform_step.jl b/lib/OrdinaryDiffEqLowOrderRK/src/fixed_timestep_perform_step.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/fixed_timestep_perform_step.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/fixed_timestep_perform_step.jl diff --git a/lib/OrdinaryLowOrderRK/src/interp_func.jl b/lib/OrdinaryDiffEqLowOrderRK/src/interp_func.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/interp_func.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/interp_func.jl diff --git a/lib/OrdinaryLowOrderRK/src/interpolants.jl b/lib/OrdinaryDiffEqLowOrderRK/src/interpolants.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/interpolants.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/interpolants.jl diff --git a/lib/OrdinaryLowOrderRK/src/low_order_rk_addsteps.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_addsteps.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/low_order_rk_addsteps.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_addsteps.jl diff --git a/lib/OrdinaryLowOrderRK/src/low_order_rk_caches.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_caches.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/low_order_rk_caches.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_caches.jl diff --git a/lib/OrdinaryLowOrderRK/src/low_order_rk_perform_step.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_perform_step.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/low_order_rk_perform_step.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_perform_step.jl diff --git a/lib/OrdinaryLowOrderRK/src/low_order_rk_tableaus.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_tableaus.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/low_order_rk_tableaus.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_tableaus.jl diff --git a/lib/OrdinaryLowOrderRK/src/split_perform_step.jl b/lib/OrdinaryDiffEqLowOrderRK/src/split_perform_step.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/src/split_perform_step.jl rename to lib/OrdinaryDiffEqLowOrderRK/src/split_perform_step.jl diff --git a/lib/OrdinaryLowOrderRK/test/owrenzen_tests.jl b/lib/OrdinaryDiffEqLowOrderRK/test/owrenzen_tests.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/test/owrenzen_tests.jl rename to lib/OrdinaryDiffEqLowOrderRK/test/owrenzen_tests.jl diff --git a/lib/OrdinaryLowOrderRK/test/runtests.jl b/lib/OrdinaryDiffEqLowOrderRK/test/runtests.jl similarity index 100% rename from lib/OrdinaryLowOrderRK/test/runtests.jl rename to lib/OrdinaryDiffEqLowOrderRK/test/runtests.jl diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 0a9930628c..519fbebcdf 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -287,7 +287,7 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA -include("../lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryDiffEqHighOrderRK.jl") +include("../lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl") using ..OrdinaryDiffEqHighOrderRK export TanYam7, DP8, Tsitpap8, PFRK87 diff --git a/src/alg_utils.jl b/src/alg_utils.jl index b33cebca70..43ccd002cf 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -21,6 +21,7 @@ end SciMLBase.forwarddiffs_model_time(alg::RosenbrockAlgorithm) = true struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end +FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() # isadaptive is defined below. From 4e76ca0a0520ca18772868214b57718f5902e95d Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 22:23:06 +0530 Subject: [PATCH 021/112] Rosenbrock --- src/algorithms.jl | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/algorithms.jl b/src/algorithms.jl index c5d60f996a..6032256fd2 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -40,6 +40,32 @@ abstract type OrdinaryDiffEqAdamsVarOrderVarStepAlgorithm <: OrdinaryDiffEqAdapt # DAE Specific Algorithms abstract type DAEAlgorithm{CS, AD, FDT, ST, CJ} <: DiffEqBase.AbstractDAEAlgorithm end +# Rosenbrock Methods +for Alg in [ + :Rosenbrock23, + :Rodas5P + ] + @eval begin + struct $Alg{CS, AD, F, P, FDT, ST, CJ, StepLimiter, StageLimiter} <: + OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + step_limiter!::StepLimiter + stage_limiter!::StageLimiter + end + function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, linsolve = nothing, + precs = DEFAULT_PRECS, step_limiter! = trivial_limiter!, + stage_limiter! = trivial_limiter!) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!), + typeof(stage_limiter!)}(linsolve, precs, step_limiter!, + stage_limiter!) + end + end + # Partitioned ODE Specific Algorithms abstract type OrdinaryDiffEqPartitionedAlgorithm <: OrdinaryDiffEqAlgorithm end abstract type OrdinaryDiffEqAdaptivePartitionedAlgorithm <: OrdinaryDiffEqAdaptiveAlgorithm end From 99fee0132913d09c6583b4f588a08604fe160da3 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 22:25:59 +0530 Subject: [PATCH 022/112] Fixes --- src/algorithms.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms.jl b/src/algorithms.jl index 6032256fd2..a614412fb1 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -714,4 +714,4 @@ function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), controller) end -TruncatedStacktraces.@truncate_stacktrace DFBDF +TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file From c9a98b2bcc79d8147a231d38fa8b4790a1d62a38 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 22:36:51 +0530 Subject: [PATCH 023/112] end --- src/algorithms.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/algorithms.jl b/src/algorithms.jl index a614412fb1..0830f10308 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -714,4 +714,6 @@ function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), controller) end -TruncatedStacktraces.@truncate_stacktrace DFBDF \ No newline at end of file +TruncatedStacktraces.@truncate_stacktrace DFBDF + +end \ No newline at end of file From 3a1627868c4b8507c069638d5f235712d77ba818 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 22:57:35 +0530 Subject: [PATCH 024/112] Fixes --- .github/workflows/Downstream.yml | 3 +- .../src/OrdinaryDiffEqDefault.jl | 6 +- .../test/runtests.jl | 2 +- .../test/runtests.jl | 2 +- src/OrdinaryDiffEq.jl | 101 +- src/alg_utils.jl | 204 +- src/algorithms.jl | 1864 +++++++++- src/algorithms/explicit_rk.jl | 463 +++ src/caches/basic_caches.jl | 87 +- src/caches/bdf_caches.jl | 658 ++++ src/caches/firk_caches.jl | 275 ++ src/caches/high_order_rk_caches.jl | 265 ++ src/caches/kencarp_kvaerno_caches.jl | 642 ++++ src/caches/low_order_rk_caches.jl | 1537 ++++++++ src/caches/rosenbrock_caches.jl | 1143 ++++++ src/caches/sdirk_caches.jl | 998 ++++++ src/dense/generic_dense.jl | 4 +- src/dense/high_order_rk_addsteps.jl | 259 ++ src/dense/interpolants.jl | 1699 +++++++++ src/dense/low_order_rk_addsteps.jl | 715 ++++ src/dense/rosenbrock_interpolants.jl | 367 ++ src/dense/stiff_addsteps.jl | 837 +++++ src/doc_utils.jl | 54 +- src/generic_rosenbrock.jl | 1810 ++++++++++ src/integrators/controllers.jl | 26 + src/integrators/integrator_interface.jl | 38 + src/integrators/integrator_utils.jl | 33 + src/interp_func.jl | 79 + src/perform_step/bdf_perform_step.jl | 1345 +++++++ src/perform_step/explicit_rk_perform_step.jl | 240 ++ src/perform_step/firk_perform_step.jl | 751 ++++ .../fixed_timestep_perform_step.jl | 490 ++- .../high_order_rk_perform_step.jl | 1153 ++++++ .../kencarp_kvaerno_perform_step.jl | 2665 ++++++++++++++ src/perform_step/low_order_rk_perform_step.jl | 2326 ++++++++++++ src/perform_step/rosenbrock_perform_step.jl | 1989 +++++++++++ src/perform_step/sdirk_perform_step.jl | 3154 +++++++++++++++++ src/perform_step/split_perform_step.jl | 50 + src/tableaus/firk_tableaus.jl | 112 + src/tableaus/high_order_rk_tableaus.jl | 1406 ++++++++ src/tableaus/low_order_rk_tableaus.jl | 2186 ++++++++++++ src/tableaus/rosenbrock_tableaus.jl | 833 +++++ src/tableaus/sdirk_tableaus.jl | 2776 +++++++++++++++ test/algconvergence/ode_firk_tests.jl | 54 + test/algconvergence/ode_rosenbrock_tests.jl | 706 ++++ test/algconvergence/owrenzen_tests.jl | 43 + test/runtests.jl | 61 +- 47 files changed, 36261 insertions(+), 250 deletions(-) create mode 100644 src/caches/bdf_caches.jl create mode 100644 src/caches/firk_caches.jl create mode 100644 src/caches/high_order_rk_caches.jl create mode 100644 src/caches/kencarp_kvaerno_caches.jl create mode 100644 src/caches/low_order_rk_caches.jl create mode 100644 src/caches/rosenbrock_caches.jl create mode 100644 src/caches/sdirk_caches.jl create mode 100644 src/dense/high_order_rk_addsteps.jl create mode 100644 src/dense/interpolants.jl create mode 100644 src/dense/low_order_rk_addsteps.jl create mode 100644 src/dense/rosenbrock_interpolants.jl create mode 100644 src/dense/stiff_addsteps.jl create mode 100644 src/generic_rosenbrock.jl create mode 100644 src/perform_step/bdf_perform_step.jl create mode 100644 src/perform_step/firk_perform_step.jl create mode 100644 src/perform_step/high_order_rk_perform_step.jl create mode 100644 src/perform_step/kencarp_kvaerno_perform_step.jl create mode 100644 src/perform_step/low_order_rk_perform_step.jl create mode 100644 src/perform_step/rosenbrock_perform_step.jl create mode 100644 src/perform_step/sdirk_perform_step.jl create mode 100644 src/perform_step/split_perform_step.jl create mode 100644 src/tableaus/firk_tableaus.jl create mode 100644 src/tableaus/high_order_rk_tableaus.jl create mode 100644 src/tableaus/low_order_rk_tableaus.jl create mode 100644 src/tableaus/rosenbrock_tableaus.jl create mode 100644 src/tableaus/sdirk_tableaus.jl create mode 100644 test/algconvergence/ode_firk_tests.jl create mode 100644 test/algconvergence/ode_rosenbrock_tests.jl create mode 100644 test/algconvergence/owrenzen_tests.jl diff --git a/.github/workflows/Downstream.yml b/.github/workflows/Downstream.yml index 4494cb1256..e2b509f28a 100644 --- a/.github/workflows/Downstream.yml +++ b/.github/workflows/Downstream.yml @@ -33,6 +33,7 @@ jobs: - {user: SciML, repo: ModelingToolkit.jl, group: All} - {user: SciML, repo: DiffEqDevTools.jl, group: Core} - {user: nathanaelbosch, repo: ProbNumDiffEq.jl, group: Downstream} + - {user: SKopecz, repo: PositiveIntegrators.jl, group: Downstream} steps: - uses: actions/checkout@v4 @@ -59,7 +60,7 @@ jobs: err isa Pkg.Resolve.ResolverError || rethrow() # If we can't resolve that means this is incompatible by SemVer and this is fine # It means we marked this as a breaking change, so we don't need to worry about - # Mistakenly introducing a breaking change, as we have intentionally made one + # mistakenly introducing a breaking change, as we have intentionally made one @info "Not compatible with this release. No problem." exception=err exit(0) # Exit immediately, as a success end diff --git a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl index ea680d5d73..ae485281ef 100644 --- a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl +++ b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl @@ -1,8 +1,8 @@ module OrdinaryDiffEqDefault -using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, FBDF, - alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, - CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch +using OrdinaryDiffEq: Vern7, Vern8, Vern9, Vern6, Tsit5, Rosenbrock23, Rodas5P, FBDF, + alg_stability_size, beta2_default, beta1_default, AutoSwitchCache, ODEIntegrator, + CompositeAlgorithm, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, AutoAlgSwitch import OrdinaryDiffEq: is_mass_matrix_alg, default_autoswitch import LinearSolve using LinearAlgebra: I, isdiag diff --git a/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl b/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl index 4aee75dc86..738c8013cc 100644 --- a/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl +++ b/lib/OrdinaryDiffEqExtrapolation/test/runtests.jl @@ -1,3 +1,3 @@ using SafeTestsets -@time @safetestset "Extrapolation Tests" include("ode_extrapolation_tests.jl") \ No newline at end of file +@time @safetestset "Extrapolation Tests" include("ode_extrapolation_tests.jl") diff --git a/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl b/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl index 6d0407a60b..7225e9390c 100644 --- a/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl +++ b/lib/OrdinaryDiffEqLowStorageRK/test/runtests.jl @@ -1,3 +1,3 @@ using SafeTestsets -@time @safetestset "Low Storage RK Tests" include("ode_low_storage_rk_tests.jl") \ No newline at end of file +@time @safetestset "Low Storage RK Tests" include("ode_low_storage_rk_tests.jl") diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 519fbebcdf..8eabc4c6ee 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -144,16 +144,30 @@ include("nlsolve/nlsolve.jl") include("nlsolve/functional.jl") include("nlsolve/newton.jl") +include("generic_rosenbrock.jl") + include("caches/basic_caches.jl") +include("caches/low_order_rk_caches.jl") +include("caches/high_order_rk_caches.jl") +include("caches/sdirk_caches.jl") +include("caches/firk_caches.jl") +include("caches/kencarp_kvaerno_caches.jl") include("caches/linear_caches.jl") include("caches/linear_nonlinear_caches.jl") +include("caches/rosenbrock_caches.jl") include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") +include("caches/bdf_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") include("caches/dae_caches.jl") include("caches/qprk_caches.jl") +include("tableaus/low_order_rk_tableaus.jl") +include("tableaus/high_order_rk_tableaus.jl") +include("tableaus/rosenbrock_tableaus.jl") +include("tableaus/sdirk_tableaus.jl") +include("tableaus/firk_tableaus.jl") include("tableaus/qprk_tableaus.jl") include("integrators/type.jl") @@ -166,18 +180,31 @@ include("initialize_dae.jl") include("wrappers.jl") include("perform_step/fixed_timestep_perform_step.jl") +include("perform_step/split_perform_step.jl") include("perform_step/linear_perform_step.jl") include("perform_step/exponential_rk_perform_step.jl") include("perform_step/explicit_rk_perform_step.jl") +include("perform_step/low_order_rk_perform_step.jl") +include("perform_step/high_order_rk_perform_step.jl") +include("perform_step/sdirk_perform_step.jl") +include("perform_step/kencarp_kvaerno_perform_step.jl") +include("perform_step/firk_perform_step.jl") +include("perform_step/rosenbrock_perform_step.jl") include("perform_step/composite_perform_step.jl") include("perform_step/adams_bashforth_moulton_perform_step.jl") include("perform_step/nordsieck_perform_step.jl") +include("perform_step/bdf_perform_step.jl") include("perform_step/prk_perform_step.jl") include("perform_step/pdirk_perform_step.jl") include("perform_step/dae_perform_step.jl") include("perform_step/qprk_perform_step.jl") include("dense/generic_dense.jl") +include("dense/interpolants.jl") +include("dense/rosenbrock_interpolants.jl") +include("dense/stiff_addsteps.jl") +include("dense/low_order_rk_addsteps.jl") +include("dense/high_order_rk_addsteps.jl") include("derivative_utils.jl") include("nordsieck_utils.jl") @@ -252,49 +279,6 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm -include("../lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl") -using ..OrdinaryDiffEqRosenbrock -export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, - Ros4LStab, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2, - Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, - RosenbrockW6S4OS, ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, - ROS3PRL2, ROK4a, - ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 - -include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") -using ..OrdinaryDiffEqBDF -export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, SBDF - MEBDF2 - -include("../lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl") -using ..OrdinaryDiffEqFIRK -export RadauIIA3, RadauIIA5 - -include("../lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl") -using ..OrdinaryDiffEqLowOrderRK -export Heun, Ralston, Midpoint, OwrenZen3, OwrenZen4, - OwrenZen5, RK4, BS3, BS5, Tsit5, DP5, Anas5, RKO65, - FRK65, RKM, MSRK5, MSRK6, PSRK4p7q6, PSRK3p6q5, - Stepanov5, SIR54, Alshina2, Alshina3, Alshina6, Euler, - PSRK3p5q4, SplitEuler - -include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") -using ..OrdinaryDiffEqSDIRK -export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, - Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, - Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, - SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, - SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, - SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA - -include("../lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl") -using ..OrdinaryDiffEqHighOrderRK -export TanYam7, DP8, Tsitpap8, PFRK87 - -include("../lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl") -using ..OrdinaryDiffEqExplicitRK -export ExplicitRK - import PrecompileTools PrecompileTools.@compile_workload begin @@ -425,19 +409,40 @@ export constructDormandPrince # Reexport the Alg Types -export FunctionMap, CompositeAlgorithm, - QPRK98 +export FunctionMap, Euler, Heun, Ralston, Midpoint, RK4, ExplicitRK, OwrenZen3, OwrenZen4, + OwrenZen5, + BS3, BS5, DP5, Tsit5, DP8, TanYam7, TsitPap8, CompositeAlgorithm, Anas5, RKO65, + FRK65, PFRK87, + RKM, MSRK5, MSRK6, Stepanov5, SIR54, QPRK98, PSRK4p7q6, PSRK3p6q5, PSRK3p5q4 + +export RadauIIA3, RadauIIA5 + +export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, + Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, + Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, + SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, + SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA export MagnusMidpoint, LinearExponential, MagnusLeapfrog, LieEuler, CayleyEuler, MagnusGauss4, MagnusNC6, MagnusGL6, MagnusGL8, MagnusNC8, MagnusGL4, MagnusAdapt4, RKMK2, RKMK4, LieRK4, CG2, CG3, CG4a +export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, + Ros4LStab, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2, + Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, + RosenbrockW6S4OS, ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, + ROS3PRL2, ROK4a, + ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 + export LawsonEuler, NorsettEuler, ETD1, ETDRK2, ETDRK3, ETDRK4, HochOst4, Exp4, EPIRK4s3A, EPIRK4s3B, EPIRK5s3, EXPRB53s3, EPIRK5P1, EPIRK5P2, ETD2, Exprb32, Exprb43 export SHLDDRK52, SHLDDRK_2N +export SplitEuler + export AB3, AB4, AB5, ABM32, ABM43, ABM54 export VCAB3, VCAB4, VCAB5, VCABM3, VCABM4, VCABM5 @@ -448,8 +453,14 @@ export IMEXEuler, IMEXEulerARK, CNAB2, CNLF2 export AN5, JVODE, JVODE_Adams, JVODE_BDF +export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF + export SBDF2, SBDF3, SBDF4 +export MEBDF2 + +export Alshina2, Alshina3, Alshina6 + export AutoSwitch, AutoTsit5, AutoDP5, AutoVern6, AutoVern7, AutoVern8, AutoVern9 diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 43ccd002cf..da79af736d 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -1,4 +1,5 @@ ## SciMLBase Trait Definitions + function SciMLBase.isautodifferentiable(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm, FunctionMap}) true @@ -20,19 +21,35 @@ function SciMLBase.forwarddiffs_model(alg::Union{OrdinaryDiffEqAdaptiveImplicitA end SciMLBase.forwarddiffs_model_time(alg::RosenbrockAlgorithm) = true -struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end -FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() - # isadaptive is defined below. ## OrdinaryDiffEq Internal Traits isfsal(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = true +isfsal(tab::DiffEqBase.ExplicitRKTableau) = tab.fsal # isfsal(alg::CompositeAlgorithm) = isfsal(alg.algs[alg.current]) +isfsal(alg::FunctionMap) = false +isfsal(alg::Rodas3P) = false +isfsal(alg::Rodas23W) = false +isfsal(alg::Rodas5) = false +isfsal(alg::Rodas5P) = false +isfsal(alg::Rodas5Pr) = false +isfsal(alg::Rodas5Pe) = false +isfsal(alg::Rodas4) = false +isfsal(alg::Rodas42) = false +isfsal(alg::Rodas4P) = false +isfsal(alg::Rodas4P2) = false # Pseudo Non-FSAL isfsal(alg::PDIRK44) = false isfsal(alg::DImplicitEuler) = false +isfsal(alg::RKO65) = false +isfsal(alg::FRK65) = true +#isfsal(alg::RKM) = false + +isfsal(alg::PSRK3p5q4) = false +isfsal(alg::PSRK3p6q5) = false +isfsal(alg::PSRK4p7q6) = false get_current_isfsal(alg, cache) = isfsal(alg) @@ -154,9 +171,12 @@ function qmin_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) isadaptive(alg) ? 1 // 5 : 0 end qmin_default(alg::CompositeAlgorithm) = maximum(qmin_default.(alg.algs)) +qmin_default(alg::DP8) = 1 // 3 qmax_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 10 qmax_default(alg::CompositeAlgorithm) = minimum(qmax_default.(alg.algs)) +qmax_default(alg::DP8) = 6 +qmax_default(alg::Union{RadauIIA3, RadauIIA5}) = 8 function has_chunksize(alg::OrdinaryDiffEqAlgorithm) return alg isa Union{OrdinaryDiffEqExponentialAlgorithm, @@ -327,8 +347,14 @@ end alg_extrapolates(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_extrapolates(alg::CompositeAlgorithm) = any(alg_extrapolates.(alg.algs)) +alg_extrapolates(alg::ImplicitEuler) = true alg_extrapolates(alg::DImplicitEuler) = true alg_extrapolates(alg::DABDF2) = true +alg_extrapolates(alg::Trapezoid) = true +alg_extrapolates(alg::SDIRK22) = true +alg_extrapolates(alg::ABDF2) = true +alg_extrapolates(alg::SBDF) = true +alg_extrapolates(alg::MEBDF2) = true alg_extrapolates(alg::MagnusLeapfrog) = true function alg_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) @@ -348,6 +374,10 @@ function get_current_adaptive_order(alg::OrdinaryDiffEqAdamsVarOrderVarStepAlgor cache.order end get_current_alg_order(alg::JVODE, cache) = get_current_adaptive_order(alg, cache) +get_current_alg_order(alg::QNDF, cache) = cache.order +get_current_alg_order(alg::FBDF, cache) = cache.order +get_current_adaptive_order(alg::QNDF, cache) = cache.order +get_current_adaptive_order(alg::FBDF, cache) = cache.order #alg_adaptive_order(alg::OrdinaryDiffEqAdaptiveAlgorithm) = error("Algorithm is adaptive with no order") function get_current_adaptive_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}, @@ -358,6 +388,10 @@ function get_current_adaptive_order(alg::CompositeAlgorithm, cache) _eval_index(alg_adaptive_order, alg.algs, cache.current)::Int end +alg_order(alg::FunctionMap) = 0 +alg_order(alg::Euler) = 1 +alg_order(alg::Heun) = 2 +alg_order(alg::Ralston) = 2 alg_order(alg::LawsonEuler) = 1 alg_order(alg::NorsettEuler) = 1 alg_order(alg::LieEuler) = 1 @@ -373,11 +407,41 @@ alg_order(alg::EPIRK5s3) = 5 alg_order(alg::EPIRK5P1) = 5 alg_order(alg::EPIRK5P2) = 5 alg_order(alg::EXPRB53s3) = 5 +alg_order(alg::SplitEuler) = 1 alg_order(alg::ETD2) = 2 alg_order(alg::Exprb32) = 3 alg_order(alg::Exprb43) = 4 +alg_order(alg::Anas5) = 5 alg_order(alg::KuttaPRK2p5) = 5 - +alg_order(alg::RKO65) = 5 +alg_order(alg::FRK65) = 6 + +alg_order(alg::Midpoint) = 2 + +alg_order(alg::RK4) = 4 +alg_order(alg::RKM) = 4 +alg_order(alg::ExplicitRK) = alg.tableau.order +alg_order(alg::MSRK5) = 5 +alg_order(alg::MSRK6) = 6 +alg_order(alg::Stepanov5) = 5 +alg_order(alg::SIR54) = 5 +alg_order(alg::PSRK4p7q6) = 4 +alg_order(alg::PSRK3p6q5) = 3 +alg_order(alg::PSRK3p5q4) = 3 + +alg_order(alg::BS3) = 3 +alg_order(alg::BS5) = 5 +alg_order(alg::OwrenZen3) = 3 +alg_order(alg::OwrenZen4) = 4 +alg_order(alg::OwrenZen5) = 5 +alg_order(alg::DP5) = 5 +alg_order(alg::Tsit5) = 5 +alg_order(alg::DP8) = 8 +alg_order(alg::TanYam7) = 7 +alg_order(alg::TsitPap8) = 8 +alg_order(alg::RadauIIA3) = 3 +alg_order(alg::RadauIIA5) = 5 +alg_order(alg::ImplicitEuler) = 1 alg_order(alg::RKMK2) = 2 alg_order(alg::RKMK4) = 4 alg_order(alg::LieRK4) = 4 @@ -394,6 +458,71 @@ alg_order(alg::MagnusGL4) = 4 alg_order(alg::MagnusAdapt4) = 4 alg_order(alg::LinearExponential) = 1 alg_order(alg::MagnusLeapfrog) = 2 +alg_order(alg::Trapezoid) = 2 +alg_order(alg::ImplicitMidpoint) = 2 +alg_order(alg::TRBDF2) = 2 +alg_order(alg::SSPSDIRK2) = 2 +alg_order(alg::SDIRK2) = 2 +alg_order(alg::SDIRK22) = 2 +alg_order(alg::Kvaerno3) = 3 +alg_order(alg::Kvaerno4) = 4 +alg_order(alg::Kvaerno5) = 5 +alg_order(alg::ESDIRK54I8L2SA) = 5 +alg_order(alg::ESDIRK436L2SA2) = 4 +alg_order(alg::ESDIRK437L2SA) = 4 +alg_order(alg::ESDIRK547L2SA2) = 5 +alg_order(alg::ESDIRK659L2SA) = 6 +alg_order(alg::KenCarp3) = 3 +alg_order(alg::CFNLIRK3) = 3 +alg_order(alg::KenCarp4) = 4 +alg_order(alg::KenCarp47) = 4 +alg_order(alg::KenCarp5) = 5 +alg_order(alg::KenCarp58) = 5 +alg_order(alg::Cash4) = 4 +alg_order(alg::SFSDIRK4) = 4 +alg_order(alg::SFSDIRK5) = 4 +alg_order(alg::SFSDIRK6) = 4 +alg_order(alg::SFSDIRK7) = 4 +alg_order(alg::SFSDIRK8) = 4 +alg_order(alg::Hairer4) = 4 +alg_order(alg::Hairer42) = 4 +alg_order(alg::PFRK87) = 8 + +alg_order(alg::ROS2) = 2 +alg_order(alg::ROS2PR) = 2 +alg_order(alg::ROS2S) = 2 +alg_order(alg::ROS3) = 3 +alg_order(alg::ROS3PR) = 3 +alg_order(alg::Scholz4_7) = 3 +alg_order(alg::Rosenbrock23) = 2 +alg_order(alg::Rodas23W) = 3 +alg_order(alg::Rosenbrock32) = 3 +alg_order(alg::ROS3P) = 3 +alg_order(alg::Rodas3) = 3 +alg_order(alg::Rodas3P) = 3 +alg_order(alg::ROS34PW1a) = 3 +alg_order(alg::ROS34PW1b) = 3 +alg_order(alg::ROS34PW2) = 3 +alg_order(alg::ROS34PW3) = 4 +alg_order(alg::ROS34PRw) = 3 +alg_order(alg::ROS3PRL) = 3 +alg_order(alg::ROS3PRL2) = 3 +alg_order(alg::ROK4a) = 4 +alg_order(alg::RosShamp4) = 4 +alg_order(alg::Veldd4) = 4 +alg_order(alg::Velds4) = 4 +alg_order(alg::GRK4T) = 4 +alg_order(alg::GRK4A) = 4 +alg_order(alg::Ros4LStab) = 4 +alg_order(alg::RosenbrockW6S4OS) = 4 +alg_order(alg::Rodas4) = 4 +alg_order(alg::Rodas42) = 4 +alg_order(alg::Rodas4P) = 4 +alg_order(alg::Rodas4P2) = 4 +alg_order(alg::Rodas5) = 5 +alg_order(alg::Rodas5P) = 5 +alg_order(alg::Rodas5Pr) = 5 +alg_order(alg::Rodas5Pe) = 5 alg_order(alg::AB3) = 3 alg_order(alg::AB4) = 4 @@ -417,20 +546,45 @@ alg_order(alg::CNLF2) = 2 alg_order(alg::AN5) = 5 alg_order(alg::JVODE) = 1 #dummy value +alg_order(alg::ABDF2) = 2 +alg_order(alg::QNDF1) = 1 +alg_order(alg::QNDF2) = 2 + +alg_order(alg::QNDF) = 1 #dummy value +alg_order(alg::FBDF) = 1 #dummy value + +alg_order(alg::SBDF) = alg.order + +alg_order(alg::MEBDF2) = 2 alg_order(alg::PDIRK44) = 4 alg_order(alg::DImplicitEuler) = 1 alg_order(alg::DABDF2) = 2 alg_order(alg::DFBDF) = 1#dummy value + +alg_order(alg::Alshina2) = 2 +alg_order(alg::Alshina3) = 3 +alg_order(alg::Alshina6) = 6 + alg_order(alg::QPRK98) = 9 alg_maximum_order(alg) = alg_order(alg) alg_maximum_order(alg::CompositeAlgorithm) = maximum(alg_order(x) for x in alg.algs) +alg_adaptive_order(alg::ExplicitRK) = alg.tableau.adaptiveorder alg_adaptive_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = alg_order(alg) - 1 +alg_adaptive_order(alg::Rosenbrock23) = 3 +alg_adaptive_order(alg::Rosenbrock32) = 2 + +alg_adaptive_order(alg::RadauIIA3) = 1 +alg_adaptive_order(alg::RadauIIA5) = 3 + +alg_adaptive_order(alg::ImplicitEuler) = 0 +alg_adaptive_order(alg::Trapezoid) = 1 # this is actually incorrect and is purposefully decreased as this tends # to track the real error much better +alg_adaptive_order(alg::ImplicitMidpoint) = 1 # this is actually incorrect and is purposefully decreased as this tends # to track the real error much better @@ -471,10 +625,16 @@ end function beta2_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) isadaptive(alg) ? 2 // (5alg_order(alg)) : 0 end +beta2_default(alg::FunctionMap) = 0 +beta2_default(alg::DP8) = 0 // 1 +beta2_default(alg::DP5) = 4 // 100 function beta1_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}, beta2) isadaptive(alg) ? 7 // (10alg_order(alg)) : 0 end +beta1_default(alg::FunctionMap, beta2) = 0 +beta1_default(alg::DP8, beta2) = typeof(beta2)(1 // alg_order(alg)) - beta2 / 5 +beta1_default(alg::DP5, beta2) = typeof(beta2)(1 // alg_order(alg)) - 3beta2 / 4 function gamma_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) isadaptive(alg) ? 9 // 10 : 0 @@ -484,12 +644,17 @@ gamma_default(alg::CompositeAlgorithm) = maximum(gamma_default, alg.algs) fac_default_gamma(alg) = false qsteady_min_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 1 +qsteady_min_default(alg::FBDF) = 9 // 10 qsteady_max_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 1 qsteady_max_default(alg::OrdinaryDiffEqAdaptiveImplicitAlgorithm) = 6 // 5 # But don't re-use Jacobian if not adaptive: too risky and cannot pull back qsteady_max_default(alg::OrdinaryDiffEqImplicitAlgorithm) = isadaptive(alg) ? 1 // 1 : 0 qsteady_max_default(alg::AN5) = 3 // 2 qsteady_max_default(alg::JVODE) = 3 // 2 +qsteady_max_default(alg::QNDF1) = 2 // 1 +qsteady_max_default(alg::QNDF2) = 2 // 1 +qsteady_max_default(alg::QNDF) = 2 // 1 +qsteady_max_default(alg::FBDF) = 2 // 1 #TODO #DiffEqBase.nlsolve_default(::QNDF, ::Val{κ}) = 1//2 @@ -500,11 +665,16 @@ end # SSP coefficients ssp_coefficient(alg) = error("$alg is not a strong stability preserving method.") +ssp_coefficient(alg::Euler) = 1 # We shouldn't do this probably. #ssp_coefficient(alg::ImplicitEuler) = Inf +ssp_coefficient(alg::SSPSDIRK2) = 4 # stability regions +alg_stability_size(alg::ExplicitRK) = alg.tableau.stability_size +alg_stability_size(alg::DP5) = 3.3066 +alg_stability_size(alg::Tsit5) = 3.5068 alg_can_repeat_jac(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_can_repeat_jac(alg::OrdinaryDiffEqNewtonAdaptiveAlgorithm) = true @@ -568,9 +738,33 @@ isstandard(alg::OrdinaryDiffEqNewtonAdaptiveAlgorithm) = alg.controller === :Sta isstandard(alg::VCABM) = true isWmethod(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false +isWmethod(alg::Rosenbrock23) = true +isWmethod(alg::Rosenbrock32) = true +isWmethod(alg::Rodas23W) = true +isWmethod(alg::ROS2S) = true +isWmethod(alg::ROS34PW1a) = true +isWmethod(alg::ROS34PW1b) = true +isWmethod(alg::ROS34PW2) = true +isWmethod(alg::ROS34PW3) = true +isWmethod(alg::ROS34PRw) = true +isWmethod(alg::ROK4a) = true +isWmethod(alg::RosenbrockW6S4OS) = true + +isesdirk(alg::TRBDF2) = true +function isesdirk(alg::Union{KenCarp3, KenCarp4, KenCarp5, KenCarp58, + Kvaerno3, Kvaerno4, Kvaerno5, ESDIRK437L2SA, + ESDIRK54I8L2SA, ESDIRK436L2SA2, ESDIRK547L2SA2, + ESDIRK659L2SA, CFNLIRK3}) + true +end isesdirk(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::CompositeAlgorithm) = all(is_mass_matrix_alg, alg.algs) +is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true is_mass_matrix_alg(alg::NewtonAlgorithm) = !isesdirk(alg) -# hack for the default alg \ No newline at end of file +# hack for the default alg +function is_mass_matrix_alg(alg::CompositeAlgorithm{ + <:Any, <:Tuple{Tsit5, Rosenbrock23, Rodas5P, FBDF, FBDF}}) + true +end diff --git a/src/algorithms.jl b/src/algorithms.jl index 0830f10308..7b7ae3ce6e 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -40,38 +40,15 @@ abstract type OrdinaryDiffEqAdamsVarOrderVarStepAlgorithm <: OrdinaryDiffEqAdapt # DAE Specific Algorithms abstract type DAEAlgorithm{CS, AD, FDT, ST, CJ} <: DiffEqBase.AbstractDAEAlgorithm end -# Rosenbrock Methods -for Alg in [ - :Rosenbrock23, - :Rodas5P - ] - @eval begin - struct $Alg{CS, AD, F, P, FDT, ST, CJ, StepLimiter, StageLimiter} <: - OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - step_limiter!::StepLimiter - stage_limiter!::StageLimiter - end - function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = nothing, - precs = DEFAULT_PRECS, step_limiter! = trivial_limiter!, - stage_limiter! = trivial_limiter!) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!), - typeof(stage_limiter!)}(linsolve, precs, step_limiter!, - stage_limiter!) - end - end - # Partitioned ODE Specific Algorithms abstract type OrdinaryDiffEqPartitionedAlgorithm <: OrdinaryDiffEqAlgorithm end abstract type OrdinaryDiffEqAdaptivePartitionedAlgorithm <: OrdinaryDiffEqAdaptiveAlgorithm end const PartitionedAlgorithm = Union{OrdinaryDiffEqPartitionedAlgorithm, OrdinaryDiffEqAdaptivePartitionedAlgorithm} +struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end +FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() + function DiffEqBase.remake(thing::OrdinaryDiffEqAlgorithm; kwargs...) T = SciMLBase.remaker_of(thing) T(; SciMLBase.struct_as_namedtuple(thing)..., kwargs...) @@ -96,6 +73,238 @@ end # RK methods +struct ExplicitRK{TabType} <: OrdinaryDiffEqAdaptiveAlgorithm + tableau::TabType +end +ExplicitRK(; tableau = ODE_DEFAULT_TABLEAU) = ExplicitRK(tableau) + +TruncatedStacktraces.@truncate_stacktrace ExplicitRK + +@inline trivial_limiter!(u, integrator, p, t) = nothing +""" + SIR54(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +5th order Explicit RK method suited for SIR-type epidemic models. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Kovalnogov2020RungeKuttaPS, +title={Runge–Kutta pairs suited for SIR‐type epidemic models}, +author={Vladislav N. Kovalnogov and Theodore E. Simos and Ch. Tsitouras}, +journal={Mathematical Methods in the Applied Sciences}, +year={2020}, +volume={44}, +pages={5210 - 5216} +} +""" +struct SIR54{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function SIR54(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + SIR54{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +# for backwards compatibility +function SIR54(stage_limiter!, step_limiter! = trivial_limiter!) + SIR54{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::SIR54) + print(io, "SIR54(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + +""" + Alshina2(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +2nd order, 2-stage Explicit Runge-Kutta Method with optimal parameters. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Alshina2008, +doi = {10.1134/s0965542508030068}, +url = {https://doi.org/10.1134/s0965542508030068}, +year = {2008}, +month = mar, +publisher = {Pleiades Publishing Ltd}, +volume = {48}, +number = {3}, +pages = {395--405}, +author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, +title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, +journal = {Computational Mathematics and Mathematical Physics} +} +""" +struct Alshina2{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function Alshina2(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + Alshina2{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +function Alshina2(stage_limiter!, step_limiter! = trivial_limiter!) + Alshina2{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::Alshina2) + print(io, "Alshina2(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + +""" + Alshina3(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +3rd order, 3-stage Explicit Runge-Kutta Method with optimal parameters. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Alshina2008, +doi = {10.1134/s0965542508030068}, +url = {https://doi.org/10.1134/s0965542508030068}, +year = {2008}, +month = mar, +publisher = {Pleiades Publishing Ltd}, +volume = {48}, +number = {3}, +pages = {395--405}, +author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, +title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, +journal = {Computational Mathematics and Mathematical Physics} +} +""" +struct Alshina3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function Alshina3(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + Alshina3{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +function Alshina3(stage_limiter!, step_limiter! = trivial_limiter!) + Alshina3{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::Alshina3) + print(io, "Alshina3(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + +""" + Alshina6(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, + step_limiter! = OrdinaryDiffEq.trivial_limiter!, + thread = OrdinaryDiffEq.False()) + +6th order, 7-stage Explicit Runge-Kutta Method with optimal parameters. + +Like SSPRK methods, this method also takes optional arguments `stage_limiter!` +and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions +of the form `limiter!(u, integrator, p, t)`. + +The argument `thread` determines whether internal broadcasting on +appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, +default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when +Julia is started with multiple threads. + +## Reference + +@article{Alshina2008, +doi = {10.1134/s0965542508030068}, +url = {https://doi.org/10.1134/s0965542508030068}, +year = {2008}, +month = mar, +publisher = {Pleiades Publishing Ltd}, +volume = {48}, +number = {3}, +pages = {395--405}, +author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, +title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, +journal = {Computational Mathematics and Mathematical Physics} +} +""" +struct Alshina6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function Alshina6(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, + thread = False()) + Alshina6{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, + step_limiter!, + thread) +end + +function Alshina6(stage_limiter!, step_limiter! = trivial_limiter!) + Alshina6{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, + step_limiter!, + False()) +end + +function Base.show(io::IO, alg::Alshina6) + print(io, "Alshina6(stage_limiter! = ", alg.stage_limiter!, + ", step_limiter! = ", alg.step_limiter!, + ", thread = ", alg.thread, ")") +end + ################################################################################ # Adams Bashforth and Adams moulton methods @@ -281,6 +490,41 @@ function CNLF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Va extrapolant) end +""" +QNDF1: Multistep Method +An adaptive order 1 quasi-constant timestep L-stable numerical differentiation function (NDF) method. +Optional parameter kappa defaults to Shampine's accuracy-optimal -0.1850. + +See also `QNDF`. +""" +struct QNDF1{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, kappa = -0.1850, + controller = :Standard, step_limiter! = trivial_limiter!) + QNDF1{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(kappa), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + kappa, + controller, + step_limiter!) +end + """ QBDF1: Multistep Method @@ -288,6 +532,40 @@ An alias of `QNDF1` with κ=0. """ QBDF1(; kwargs...) = QNDF1(; kappa = 0, kwargs...) +""" +QNDF2: Multistep Method +An adaptive order 2 quasi-constant timestep L-stable numerical differentiation function (NDF) method. + +See also `QNDF`. +""" +struct QNDF2{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, kappa = -1 // 9, + controller = :Standard, step_limiter! = trivial_limiter!) + QNDF2{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(kappa), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + kappa, + controller, + step_limiter!) +end + """ QBDF2: Multistep Method @@ -295,6 +573,51 @@ An alias of `QNDF2` with κ=0. """ QBDF2(; kwargs...) = QNDF2(; kappa = 0, kwargs...) +""" +QNDF: Multistep Method +An adaptive order quasi-constant timestep NDF method. +Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). + +@article{shampine1997matlab, +title={The matlab ode suite}, +author={Shampine, Lawrence F and Reichelt, Mark W}, +journal={SIAM journal on scientific computing}, +volume={18}, +number={1}, +pages={1--22}, +year={1997}, +publisher={SIAM} +} +""" +struct QNDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, kappa = promote(-0.1850, -1 // 9, -0.0823, -0.0415, 0), + controller = :Standard, step_limiter! = trivial_limiter!) where {MO} + QNDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(kappa), typeof(step_limiter!)}( + max_order, linsolve, nlsolve, precs, κ, tol, + extrapolant, kappa, controller, step_limiter!) +end + TruncatedStacktraces.@truncate_stacktrace QNDF """ @@ -304,6 +627,101 @@ An alias of `QNDF` with κ=0. """ QBDF(; kwargs...) = QNDF(; kappa = tuple(0 // 1, 0 // 1, 0 // 1, 0 // 1, 0 // 1), kwargs...) +""" +FBDF: Fixed leading coefficient BDF + +An adaptive order quasi-constant timestep NDF method. +Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). + +@article{shampine2002solving, +title={Solving 0= F (t, y (t), y′(t)) in Matlab}, +author={Shampine, Lawrence F}, +year={2002}, +publisher={Walter de Gruyter GmbH \\& Co. KG} +} +""" +struct FBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function FBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard, step_limiter! = trivial_limiter!) where {MO} + FBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(step_limiter!)}( + max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace FBDF + +""" +Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. Implicit-Explicit Methods for Time- +Dependent Partial Differential Equations. 1995 Society for Industrial and Applied Mathematics +Journal on Numerical Analysis, 32(3), pp 797-823, 1995. doi: https://doi.org/10.1137/0732037 +""" +struct SBDF{CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + order::Int + ark::Bool +end + +function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, ark = false) + SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(linsolve, + nlsolve, + precs, + κ, + tol, + extrapolant, + order, + ark) +end + +# All keyword form needed for remake +function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, + order, ark = false) + SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(linsolve, + nlsolve, + precs, + κ, + tol, + extrapolant, + order, + ark) +end + """ IMEXEuler(;kwargs...) @@ -470,87 +888,1301 @@ struct CayleyEuler <: OrdinaryDiffEqAlgorithm end ################################################################################ -################################################################################ - -###################################### +# FIRK Methods -for Alg in [:LawsonEuler, :NorsettEuler, :ETDRK2, :ETDRK3, :ETDRK4, :HochOst4] - """ - Hochbruck, Marlis, and Alexander Ostermann. “Exponential Integrators.” Acta - Numerica 19 (2010): 209–286. doi:10.1017/S0962492910000048. - """ - @eval struct $Alg{CS, AD, FDT, ST, CJ} <: - OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} - krylov::Bool - m::Int - iop::Int - end - @eval function $Alg(; krylov = false, m = 30, iop = 0, autodiff = true, - standardtag = Val{true}(), concrete_jac = nothing, - chunk_size = Val{0}(), - diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), - diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(krylov, - m, - iop) - end -end -const ETD1 = NorsettEuler # alias -for Alg in [:Exprb32, :Exprb43] - @eval struct $Alg{CS, AD, FDT, ST, CJ} <: - OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD, FDT, ST, CJ} - m::Int - iop::Int - end - @eval function $Alg(; m = 30, iop = 0, autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, chunk_size = Val{0}(), - diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), - diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(m, - iop) - end -end -for Alg in [:Exp4, :EPIRK4s3A, :EPIRK4s3B, :EPIRK5s3, :EXPRB53s3, :EPIRK5P1, :EPIRK5P2] - @eval struct $Alg{CS, AD, FDT, ST, CJ} <: - OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} - adaptive_krylov::Bool - m::Int - iop::Int - end - @eval function $Alg(; adaptive_krylov = true, m = 30, iop = 0, autodiff = true, - standardtag = Val{true}(), concrete_jac = nothing, - chunk_size = Val{0}(), diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), diff_type, - _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(adaptive_krylov, - m, - iop) - end -end """ -ETD2: Exponential Runge-Kutta Method -Second order Exponential Time Differencing method (in development). +@article{hairer1999stiff, +title={Stiff differential equations solved by Radau methods}, +author={Hairer, Ernst and Wanner, Gerhard}, +journal={Journal of Computational and Applied Mathematics}, +volume={111}, +number={1-2}, +pages={93--111}, +year={1999}, +publisher={Elsevier} +} + +RadauIIA3: Fully-Implicit Runge-Kutta Method +An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. """ -struct ETD2 <: - OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end - -######################################### - -######################################### +struct RadauIIA3{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + extrapolant::Symbol + κ::Tol + maxiters::Int + fast_convergence_cutoff::C1 + new_W_γdt_cutoff::C2 + controller::Symbol + step_limiter!::StepLimiter +end -struct CompositeAlgorithm{CS, T, F} <: OrdinaryDiffEqCompositeAlgorithm - algs::T - choice_function::F - function CompositeAlgorithm(algs::T, choice_function::F) where {T, F} - CS = mapreduce(alg -> has_chunksize(alg) ? get_chunksize_int(alg) : 0, max, algs) - new{CS, T, F}(algs, choice_function) - end +function RadauIIA3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, + extrapolant = :dense, fast_convergence_cutoff = 1 // 5, + new_W_γdt_cutoff = 1 // 5, + controller = :Predictive, κ = nothing, maxiters = 10, + step_limiter! = trivial_limiter!) + RadauIIA3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(fast_convergence_cutoff), + typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, + precs, + extrapolant, + κ, + maxiters, + fast_convergence_cutoff, + new_W_γdt_cutoff, + controller, + step_limiter!) end -TruncatedStacktraces.@truncate_stacktrace CompositeAlgorithm 1 +TruncatedStacktraces.@truncate_stacktrace RadauIIA3 -if isdefined(Base, :Experimental) && isdefined(Base.Experimental, :silence!) - Base.Experimental.silence!(CompositeAlgorithm) +""" +@article{hairer1999stiff, +title={Stiff differential equations solved by Radau methods}, +author={Hairer, Ernst and Wanner, Gerhard}, +journal={Journal of Computational and Applied Mathematics}, +volume={111}, +number={1-2}, +pages={93--111}, +year={1999}, +publisher={Elsevier} +} + +RadauIIA5: Fully-Implicit Runge-Kutta Method +An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. +""" +struct RadauIIA5{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + smooth_est::Bool + extrapolant::Symbol + κ::Tol + maxiters::Int + fast_convergence_cutoff::C1 + new_W_γdt_cutoff::C2 + controller::Symbol + step_limiter!::StepLimiter +end + +function RadauIIA5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, + extrapolant = :dense, fast_convergence_cutoff = 1 // 5, + new_W_γdt_cutoff = 1 // 5, + controller = :Predictive, κ = nothing, maxiters = 10, smooth_est = true, + step_limiter! = trivial_limiter!) + RadauIIA5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(fast_convergence_cutoff), + typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, + precs, + smooth_est, + extrapolant, + κ, + maxiters, + fast_convergence_cutoff, + new_W_γdt_cutoff, + controller, + step_limiter!) +end +TruncatedStacktraces.@truncate_stacktrace RadauIIA5 + +################################################################################ + +# SDIRK Methods +""" +ImplicitEuler: SDIRK Method +A 1st order implicit solver. A-B-L-stable. Adaptive timestepping through a divided differences estimate via memory. +Strong-stability preserving (SSP). +""" +struct ImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function ImplicitEuler(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :PI, step_limiter! = trivial_limiter!) + ImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, precs, extrapolant, controller, step_limiter!) +end +""" +ImplicitMidpoint: SDIRK Method +A second order A-stable symplectic and symmetric implicit solver. +Good for highly stiff equations which need symplectic integration. +""" +struct ImplicitMidpoint{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + step_limiter!::StepLimiter +end + +function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, step_limiter! = trivial_limiter!) + ImplicitMidpoint{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + step_limiter!) +end + +""" +Andre Vladimirescu. 1994. The Spice Book. John Wiley & Sons, Inc., New York, +NY, USA. + +Trapezoid: SDIRK Method +A second order A-stable symmetric ESDIRK method. +"Almost symplectic" without numerical dampening. +Also known as Crank-Nicolson when applied to PDEs. Adaptive timestepping via divided +differences approximation to the second derivative terms in the local truncation error +estimate (the SPICE approximation strategy). +""" +struct Trapezoid{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function Trapezoid(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + controller, + step_limiter!) +end + +""" +@article{hosea1996analysis, +title={Analysis and implementation of TR-BDF2}, +author={Hosea, ME and Shampine, LF}, +journal={Applied Numerical Mathematics}, +volume={20}, +number={1-2}, +pages={21--37}, +year={1996}, +publisher={Elsevier} +} + +TRBDF2: SDIRK Method +A second order A-B-L-S-stable one-step ESDIRK method. +Includes stiffness-robust error estimates for accurate adaptive timestepping, smoothed derivatives for highly stiff and oscillatory problems. +""" +struct TRBDF2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function TRBDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + TRBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace TRBDF2 + +""" +@article{hindmarsh2005sundials, +title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, +author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, +journal={ACM Transactions on Mathematical Software (TOMS)}, +volume={31}, +number={3}, +pages={363--396}, +year={2005}, +publisher={ACM} +} + +SDIRK2: SDIRK Method +An A-B-L stable 2nd order SDIRK method +""" +struct SDIRK2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function SDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + SDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}( + linsolve, nlsolve, precs, smooth_est, extrapolant, + controller, + step_limiter!) +end + +struct SDIRK22{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function SDIRK22(; + chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + controller, + step_limiter!) +end + +struct SSPSDIRK2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} # Not adaptive + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end + +function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :constant, + controller = :PI) + SSPSDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno3: SDIRK Method +An A-L stable stiffly-accurate 3rd order ESDIRK method +""" +struct Kvaerno3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp3: SDIRK Method +An A-L stable stiffly-accurate 3rd order ESDIRK method with splitting +""" +struct KenCarp3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +struct CFNLIRK3{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function CFNLIRK3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + CFNLIRK3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +""" +@article{hindmarsh2005sundials, +title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, +author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, +journal={ACM Transactions on Mathematical Software (TOMS)}, +volume={31}, +number={3}, +pages={363--396}, +year={2005}, +publisher={ACM} +} + +Cash4: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Cash4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + embedding::Int + controller::Symbol +end +function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, embedding = 3) + Cash4{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( + linsolve, + nlsolve, + precs, + smooth_est, + extrapolant, + embedding, + controller) +end + +struct SFSDIRK4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function SFSDIRK4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK5{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK6{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK6(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK6{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK7{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK7(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK7{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK8{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK8(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK8{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +""" +E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and +differential-algebraic problems. Computational mathematics (2nd revised ed.), +Springer (1996) + +Hairer4: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Hairer4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function Hairer4(; + chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + Hairer4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and +differential-algebraic problems. Computational mathematics (2nd revised ed.), +Springer (1996) + +Hairer42: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Hairer42{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function Hairer42(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + Hairer42{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno4: SDIRK Method +An A-L stable stiffly-accurate 4th order ESDIRK method. +""" +struct Kvaerno4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno5: SDIRK Method +An A-L stable stiffly-accurate 5th order ESDIRK method +""" +struct Kvaerno5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp4: SDIRK Method +An A-L stable stiffly-accurate 4th order ESDIRK method with splitting +""" +struct KenCarp4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace KenCarp4 + +""" +@article{kennedy2019higher, +title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, +author={Kennedy, Christopher A and Carpenter, Mark H}, +journal={Applied Numerical Mathematics}, +volume={136}, +pages={183--205}, +year={2019}, +publisher={Elsevier} +} + +KenCarp47: SDIRK Method +An A-L stable stiffly-accurate 4th order seven-stage ESDIRK method with splitting +""" +struct KenCarp47{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function KenCarp47(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + KenCarp47{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp5: SDIRK Method +An A-L stable stiffly-accurate 5th order ESDIRK method with splitting +""" +struct KenCarp5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end +""" +@article{kennedy2019higher, +title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, +author={Kennedy, Christopher A and Carpenter, Mark H}, +journal={Applied Numerical Mathematics}, +volume={136}, +pages={183--205}, +year={2019}, +publisher={Elsevier} +} + +KenCarp58: SDIRK Method +An A-L stable stiffly-accurate 5th order eight-stage ESDIRK method with splitting +""" +struct KenCarp58{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function KenCarp58(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + KenCarp58{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +# `smooth_est` is not necessary, as the embedded method is also L-stable +struct ESDIRK54I8L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK54I8L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK436L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK436L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK437L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK437L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK547L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK547L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} + +Currently has STABILITY ISSUES, causing it to fail the adaptive tests. +Check issue https://github.com/SciML/OrdinaryDiffEq.jl/issues/1933 for more details. +} +""" +struct ESDIRK659L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK659L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +################################################################################ + +# Rosenbrock Methods + +#= +#### Rosenbrock23, Rosenbrock32, ode23s, ModifiedRosenbrockIntegrator + +- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of +Scientific Computing, 18 (1), pp. 1-22. + +#### ROS2 + +- J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems + https://doi.org/10.1137/S1064827597326651 + +#### ROS3P + +- Lang, J. & Verwer, ROS3P—An Accurate Third-Order Rosenbrock Solver Designed for + Parabolic Problems J. BIT Numerical Mathematics (2001) 41: 731. doi:10.1023/A:1021900219772 + +#### ROS3, Rodas3, Ros4LStab, Rodas4, Rodas42 + +- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and + differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) + +#### ROS2PR, ROS2S, ROS3PR, Scholz4_7 +-Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 + +#### RosShamp4 + +- L. F. Shampine, Implementation of Rosenbrock Methods, ACM Transactions on + Mathematical Software (TOMS), 8: 2, 93-113. doi:10.1145/355993.355994 + +#### Veldd4, Velds4 + +- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. + doi:10.1007/BF02243574 + +#### GRK4T, GRK4A + +- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control + for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 + +#### Rodas23W, Rodas3P + +- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate for dense output and Julia implementation, + in progress + +#### Rodas4P + +- Steinebach G. Order-reduction of ROW-methods for DAEs and method of lines + applications. Preprint-Nr. 1741, FB Mathematik, TH Darmstadt; 1995. + +#### Rodas4P2 +- Steinebach G. (2020) Improvement of Rosenbrock-Wanner Method RODASP. + In: Reis T., Grundel S., Schoeps S. (eds) Progress in Differential-Algebraic Equations II. + Differential-Algebraic Equations Forum. Springer, Cham. https://doi.org/10.1007/978-3-030-53905-4_6 + +#### Rodas5 +- Di Marzo G. RODAS5(4) – Méthodes de Rosenbrock d’ordre 5(4) adaptées aux problemes +différentiels-algébriques. MSc mathematics thesis, Faculty of Science, +University of Geneva, Switzerland. + +#### ROS34PRw +-Joachim Rang, Improved traditional Rosenbrock–Wanner methods for stiff ODEs and DAEs, + Journal of Computational and Applied Mathematics, + https://doi.org/10.1016/j.cam.2015.03.010 + +#### ROS3PRL, ROS3PRL2 +-Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 + +#### ROK4a +- Tranquilli, Paul and Sandu, Adrian (2014): + Rosenbrock--Krylov Methods for Large Systems of Differential Equations + https://doi.org/10.1137/130923336 + +#### Rodas5P +- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks within the Julia Differential Equations package. + In: BIT Numerical Mathematics, 63(2), 2023 + + #### Rodas23W, Rodas3P, Rodas5Pe, Rodas5Pr +- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - + Preprint 2024 + https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf + +=# + +for Alg in [ + :ROS2, + :ROS2PR, + :ROS2S, + :ROS3, + :ROS3PR, + :Scholz4_7, + :ROS34PW1a, + :ROS34PW1b, + :ROS34PW2, + :ROS34PW3, + :ROS34PRw, + :ROS3PRL, + :ROS3PRL2, + :ROK4a, + :RosShamp4, + :Veldd4, + :Velds4, + :GRK4T, + :GRK4A, + :Ros4LStab] + @eval begin + struct $Alg{CS, AD, F, P, FDT, ST, CJ} <: + OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + end + function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, linsolve = nothing, precs = DEFAULT_PRECS) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + precs) + end + end + + @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 +end + +# for Rosenbrock methods with step_limiter +for Alg in [ + :Rosenbrock23, + :Rosenbrock32, + :ROS3P, + :Rodas3, + :Rodas23W, + :Rodas3P, + :Rodas4, + :Rodas42, + :Rodas4P, + :Rodas4P2, + :Rodas5, + :Rodas5P, + :Rodas5Pe, + :Rodas5Pr] + @eval begin + struct $Alg{CS, AD, F, P, FDT, ST, CJ, StepLimiter, StageLimiter} <: + OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P + step_limiter!::StepLimiter + stage_limiter!::StageLimiter + end + function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, linsolve = nothing, + precs = DEFAULT_PRECS, step_limiter! = trivial_limiter!, + stage_limiter! = trivial_limiter!) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!), + typeof(stage_limiter!)}(linsolve, precs, step_limiter!, + stage_limiter!) + end + end + + @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 +end +struct GeneralRosenbrock{CS, AD, F, ST, CJ, TabType} <: + OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, Val{:forward}, ST, CJ} + tableau::TabType + factorization::F +end + +function GeneralRosenbrock(; chunk_size = Val{0}(), autodiff = true, + standardtag = Val{true}(), concrete_jac = nothing, + factorization = lu!, tableau = ROSENBROCK_DEFAULT_TABLEAU) + GeneralRosenbrock{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(factorization), + _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(tableau)}(tableau, + factorization) +end + +@doc rosenbrock_wanner_docstring( + """ + A 4th order L-stable Rosenbrock-W method (fixed step only). + """, + "RosenbrockW6S4OS", + references = """ + https://doi.org/10.1016/j.cam.2009.09.017 + """) +struct RosenbrockW6S4OS{CS, AD, F, P, FDT, ST, CJ} <: + OrdinaryDiffEqRosenbrockAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + precs::P +end +function RosenbrockW6S4OS(; chunk_size = Val{0}(), autodiff = true, + standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:central}, + linsolve = nothing, + precs = DEFAULT_PRECS) + RosenbrockW6S4OS{_unwrap_val(chunk_size), + _unwrap_val(autodiff), typeof(linsolve), typeof(precs), diff_type, + _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, + precs) +end + +###################################### + +for Alg in [:LawsonEuler, :NorsettEuler, :ETDRK2, :ETDRK3, :ETDRK4, :HochOst4] + """ + Hochbruck, Marlis, and Alexander Ostermann. “Exponential Integrators.” Acta + Numerica 19 (2010): 209–286. doi:10.1017/S0962492910000048. + """ + @eval struct $Alg{CS, AD, FDT, ST, CJ} <: + OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} + krylov::Bool + m::Int + iop::Int + end + @eval function $Alg(; krylov = false, m = 30, iop = 0, autodiff = true, + standardtag = Val{true}(), concrete_jac = nothing, + chunk_size = Val{0}(), + diff_type = Val{:forward}) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), + diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(krylov, + m, + iop) + end +end +const ETD1 = NorsettEuler # alias +for Alg in [:Exprb32, :Exprb43] + @eval struct $Alg{CS, AD, FDT, ST, CJ} <: + OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD, FDT, ST, CJ} + m::Int + iop::Int + end + @eval function $Alg(; m = 30, iop = 0, autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, chunk_size = Val{0}(), + diff_type = Val{:forward}) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), + diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(m, + iop) + end +end +for Alg in [:Exp4, :EPIRK4s3A, :EPIRK4s3B, :EPIRK5s3, :EXPRB53s3, :EPIRK5P1, :EPIRK5P2] + @eval struct $Alg{CS, AD, FDT, ST, CJ} <: + OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} + adaptive_krylov::Bool + m::Int + iop::Int + end + @eval function $Alg(; adaptive_krylov = true, m = 30, iop = 0, autodiff = true, + standardtag = Val{true}(), concrete_jac = nothing, + chunk_size = Val{0}(), diff_type = Val{:forward}) + $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), diff_type, + _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(adaptive_krylov, + m, + iop) + end +end +struct SplitEuler <: + OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end +""" +ETD2: Exponential Runge-Kutta Method +Second order Exponential Time Differencing method (in development). +""" +struct ETD2 <: + OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end + +######################################### + +""" +E. Alberdi Celayaa, J. J. Anza Aguirrezabalab, P. Chatzipantelidisc. Implementation of +an Adaptive BDF2 Formula and Comparison with The MATLAB Ode15s. Procedia Computer Science, +29, pp 1014-1026, 2014. doi: https://doi.org/10.1016/j.procs.2014.05.091 + +ABDF2: Multistep Method +An adaptive order 2 L-stable fixed leading coefficient multistep BDF method. +""" +struct ABDF2{CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function ABDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + κ = nothing, tol = nothing, linsolve = nothing, precs = DEFAULT_PRECS, + nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :Standard, step_limiter! = trivial_limiter!) + ABDF2{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(step_limiter!)}(linsolve, nlsolve, precs, κ, tol, + smooth_est, extrapolant, controller, step_limiter!) +end + +######################################### + +struct CompositeAlgorithm{CS, T, F} <: OrdinaryDiffEqCompositeAlgorithm + algs::T + choice_function::F + function CompositeAlgorithm(algs::T, choice_function::F) where {T, F} + CS = mapreduce(alg -> has_chunksize(alg) ? get_chunksize_int(alg) : 0, max, algs) + new{CS, T, F}(algs, choice_function) + end +end + +TruncatedStacktraces.@truncate_stacktrace CompositeAlgorithm 1 + +if isdefined(Base, :Experimental) && isdefined(Base.Experimental, :silence!) + Base.Experimental.silence!(CompositeAlgorithm) end mutable struct AutoSwitchCache{nAlg, sAlg, tolType, T} @@ -608,7 +2240,30 @@ struct AutoSwitch{nAlg, sAlg, tolType, T} switch_max::Int end -############################################################################### +################################################################################ +""" +MEBDF2: Multistep Method +The second order Modified Extended BDF method, which has improved stability properties over the standard BDF. +Fixed timestep only. +""" +struct MEBDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function MEBDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant) + MEBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end ################################################# """ @@ -634,11 +2289,12 @@ function PDIRK44(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{tru end ### Algorithm Groups -#ABDF2 SBDF SBDF, KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, CFNLIRK3 const MultistepAlgorithms = Union{ + ABDF2, AB3, AB4, AB5, ABM32, ABM43, ABM54} -const SplitAlgorithms = Union{CNAB2, CNLF2} +const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF, + KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, CFNLIRK3} #= struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} @@ -715,5 +2371,3 @@ function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), end TruncatedStacktraces.@truncate_stacktrace DFBDF - -end \ No newline at end of file diff --git a/src/algorithms/explicit_rk.jl b/src/algorithms/explicit_rk.jl index 086d0fcbd6..aed2bc29b7 100644 --- a/src/algorithms/explicit_rk.jl +++ b/src/algorithms/explicit_rk.jl @@ -6,9 +6,472 @@ function Base.show(io::IO, alg::OrdinaryDiffEqAlgorithm) print(io, ")") end +@doc explicit_rk_docstring( + "The second order Heun's method. Uses embedded Euler method for adaptivity.", + "Heun") +Base.@kwdef struct Heun{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Heun(stage_limiter!, step_limiter! = trivial_limiter!) + Heun(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "The optimized second order midpoint method. Uses embedded Euler method for adaptivity.", + "Ralston") +Base.@kwdef struct Ralston{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Ralston(stage_limiter!, step_limiter! = trivial_limiter!) + Ralston(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "The second order midpoint method. Uses embedded Euler method for adaptivity.", + "Midpoint") +Base.@kwdef struct Midpoint{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Midpoint(stage_limiter!, step_limiter! = trivial_limiter!) + Midpoint(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("The canonical Runge-Kutta Order 4 method. +Uses a defect control for adaptive stepping using maximum error over the whole interval.", + "RK4", + references = "@article{shampine2005solving, + title={Solving ODEs and DDEs with residual control}, + author={Shampine, LF}, + journal={Applied Numerical Mathematics}, + volume={52}, + number={1}, + pages={113--127}, + year={2005}, + publisher={Elsevier} + }") +Base.@kwdef struct RK4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function RK4(stage_limiter!, step_limiter! = trivial_limiter!) + RK4(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("TBD", "RKM") +Base.@kwdef struct RKM{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function RKM(stage_limiter!, step_limiter! = trivial_limiter!) + RKM(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("4-stage Pseudo-Symplectic Explicit RK method.", "3p5q(4)", + references = "@article{Aubry1998, + author = {A. Aubry and P. Chartier}, + journal = {BIT Numer. Math.}, + title = {Pseudo-symplectic {R}unge-{K}utta methods}, + year = {1998}, + }, + @article{Capuano2017, + title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, + journal = {J. Comput. Phys.}, + year = {2017}, + author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") +Base.@kwdef struct PSRK3p5q4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end + +@doc explicit_rk_docstring("5-stage Pseudo-Symplectic Explicit RK method.", "3p6q(5)", + references = "@article{Aubry1998, + author = {A. Aubry and P. Chartier}, + journal = {BIT Numer. Math.}, + title = {Pseudo-symplectic {R}unge-{K}utta methods}, + year = {1998}, + }, + @article{Capuano2017, + title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, + journal = {J. Comput. Phys.}, + year = {2017}, + author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") +Base.@kwdef struct PSRK3p6q5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end + +@doc explicit_rk_docstring("6-stage Pseudo-Symplectic Explicit RK method.", "4p7q(6)", + references = "@article{Aubry1998, + author = {A. Aubry and P. Chartier}, + journal = {BIT Numer. Math.}, + title = {Pseudo-symplectic {R}unge-{K}utta methods}, + volume = {38}, + PAGES = {439-461}, + year = {1998}, + }, + @article{Capuano2017, + title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, + journal = {J. Comput. Phys.}, + volume = {328}, + pages = {86-94}, + year = {2017}, + issn = {0021-9991}, + doi = {https://doi.org/10.1016/j.jcp.2016.10.040}, + author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") +Base.@kwdef struct PSRK4p7q6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end + +@doc explicit_rk_docstring("5th order Explicit RK method.", "MSRK5", + references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Figure 3.") +Base.@kwdef struct MSRK5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function MSRK5(stage_limiter!, step_limiter! = trivial_limiter!) + MSRK5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("6th order Explicit RK method.", "MSRK6", + references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Table4") +Base.@kwdef struct MSRK6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function MSRK6(stage_limiter!, step_limiter! = trivial_limiter!) + MSRK6(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("5th order Explicit RK method.", + "Stepanov5", + references = "@article{Stepanov2021Embedded5, + title={Embedded (4, 5) pairs of explicit 7-stage Runge–Kutta methods with FSAL property}, + author={Misha Stepanov}, + journal={Calcolo}, + year={2021}, + volume={59} + }") +Base.@kwdef struct Stepanov5{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function Stepanov5(stage_limiter!, step_limiter! = trivial_limiter!) + Stepanov5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("4th order Runge-Kutta method designed for periodic problems.", + "Anas5", + extra_keyword_description = """- `w`: a periodicity estimate, which when accurate the method becomes 5th order + (and is otherwise 4th order with less error for better estimates). + """, + extra_keyword_default = "w = 1") +Base.@kwdef struct Anas5{StageLimiter, StepLimiter, Thread, T} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + w::T = 1 +end +# for backwards compatibility +function Anas5(stage_limiter!, step_limiter! = trivial_limiter!; w = 1) + Anas5(stage_limiter!, step_limiter!, False(), w) +end + +@doc explicit_rk_docstring("5th order Explicit RK method.", "RKO5", + references = "Tsitouras, Ch. \"Explicit Runge–Kutta methods for starting integration of + Lane–Emden problem.\" Applied Mathematics and Computation 354 (2019): 353-364. + doi: https://doi.org/10.1016/j.amc.2019.02.047") +Base.@kwdef struct RKO65{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function RKO65(stage_limiter!, step_limiter! = trivial_limiter!) + RKO65(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Owren-Zennaro optimized interpolation 3/2 method (free 3rd order interpolant).", + "OwrenZen3", + references = "@article{owren1992derivation, + title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, + author={Owren, Brynjulf and Zennaro, Marino}, + journal={SIAM journal on scientific and statistical computing}, + volume={13}, + number={6}, + pages={1488--1501}, + year={1992}, + publisher={SIAM} + }") +Base.@kwdef struct OwrenZen3{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function OwrenZen3(stage_limiter!, step_limiter! = trivial_limiter!) + OwrenZen3(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Owren-Zennaro optimized interpolation 4/3 method (free 4th order interpolant).", + "OwrenZen4", + references = "@article{owren1992derivation, + title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, + author={Owren, Brynjulf and Zennaro, Marino}, + journal={SIAM journal on scientific and statistical computing}, + volume={13}, + number={6}, + pages={1488--1501}, + year={1992}, + publisher={SIAM} + }") +Base.@kwdef struct OwrenZen4{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function OwrenZen4(stage_limiter!, step_limiter! = trivial_limiter!) + OwrenZen4(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Owren-Zennaro optimized interpolation 5/4 method (free 5th order interpolant).", + "OwrenZen5", + references = "@article{owren1992derivation, + title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, + author={Owren, Brynjulf and Zennaro, Marino}, + journal={SIAM journal on scientific and statistical computing}, + volume={13}, + number={6}, + pages={1488--1501}, + year={1992}, + publisher={SIAM} + }") +Base.@kwdef struct OwrenZen5{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function OwrenZen5(stage_limiter!, step_limiter! = trivial_limiter!) + OwrenZen5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "A third-order, four-stage explicit FSAL Runge-Kutta method with embedded error +estimator of Bogacki and Shampine.", + "BS3", + references = "@article{bogacki19893, + title={A 3 (2) pair of Runge-Kutta formulas}, + author={Bogacki, Przemyslaw and Shampine, Lawrence F}, + journal={Applied Mathematics Letters}, + volume={2}, + number={4}, + pages={321--325}, + year={1989}, + publisher={Elsevier} + }") +Base.@kwdef struct BS3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function BS3(stage_limiter!, step_limiter! = trivial_limiter!) + BS3(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Dormand-Prince's 5/4 Runge-Kutta method. (free 4th order interpolant).", + "DP5", + references = "@article{dormand1980family, + title={A family of embedded Runge-Kutta formulae}, + author={Dormand, John R and Prince, Peter J}, + journal={Journal of computational and applied mathematics}, + volume={6}, + number={1}, + pages={19--26}, + year={1980}, + publisher={Elsevier} + }") +Base.@kwdef struct DP5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function DP5(stage_limiter!, step_limiter! = trivial_limiter!) + DP5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "A fifth-order explicit Runge-Kutta method with embedded error +estimator of Tsitouras. Free 4th order interpolant.", "Tsit5", + references = "@article{tsitouras2011runge, + title={Runge--Kutta pairs of order 5 (4) satisfying only the first column simplifying assumption}, + author={Tsitouras, Ch}, + journal={Computers \\& Mathematics with Applications}, + volume={62}, + number={2}, + pages={770--775}, + year={2011}, + publisher={Elsevier} + }") +Base.@kwdef struct Tsit5{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +TruncatedStacktraces.@truncate_stacktrace Tsit5 3 +# for backwards compatibility +function Tsit5(stage_limiter!, step_limiter! = trivial_limiter!) + Tsit5(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Hairer's 8/5/3 adaption of the Dormand-Prince Runge-Kutta method. (7th order interpolant).", + "DP8", + references = "E. Hairer, S.P. Norsett, G. Wanner, (1993) Solving Ordinary Differential Equations I. + Nonstiff Problems. 2nd Edition. Springer Series in Computational Mathematics, + Springer-Verlag.") +Base.@kwdef struct DP8{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function DP8(stage_limiter!, step_limiter! = trivial_limiter!) + DP8(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring( + "Tanaka-Yamashita 7 Runge-Kutta method. (7th order interpolant).", + "TanYam7", + references = "Tanaka M., Muramatsu S., Yamashita S., (1992), On the Optimization of Some Nine-Stage + Seventh-order Runge-Kutta Method, Information Processing Society of Japan, + 33 (12), pp. 1512-1526.") +Base.@kwdef struct TanYam7{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function TanYam7(stage_limiter!, step_limiter! = trivial_limiter!) + TanYam7(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("Tsitouras-Papakostas 8/7 Runge-Kutta method.", "TsitPap8") +Base.@kwdef struct TsitPap8{StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() +end +# for backwards compatibility +function TsitPap8(stage_limiter!, step_limiter! = trivial_limiter!) + TsitPap8(stage_limiter!, step_limiter!, False()) +end + +@doc explicit_rk_docstring("Zero Dissipation Runge-Kutta of 6th order.", "FRK65", + extra_keyword_description = """- `omega`: a periodicity phase estimate, + when accurate this method results in zero numerical dissipation. + """, + extra_keyword_default = "omega = 0.0") +Base.@kwdef struct FRK65{StageLimiter, StepLimiter, Thread, T} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + omega::T = 0.0 +end + +# for backwards compatibility +function FRK65(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) + FRK65(stage_limiter!, step_limiter!, False(), omega) +end + +@doc explicit_rk_docstring("Phase-fitted Runge-Kutta of 8th order.", "PFRK87", + extra_keyword_description = """- `omega`: a periodicity phase estimate, + when accurate this method results in zero numerical dissipation. + """, + extra_keyword_default = "omega = 0.0") +Base.@kwdef struct PFRK87{StageLimiter, StepLimiter, Thread, T} <: + OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + omega::T = 0.0 +end +# for backwards compatibility +function PFRK87(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) + PFRK87(stage_limiter!, step_limiter!, False(), omega) +end + +@doc explicit_rk_docstring( + "Bogacki-Shampine 5/4 Runge-Kutta method. (lazy 5th order interpolant).", + "BS5", + references = "@article{bogacki1996efficient, + title={An efficient runge-kutta (4, 5) pair}, + author={Bogacki, P and Shampine, Lawrence F}, + journal={Computers \\& Mathematics with Applications}, + volume={32}, + number={6}, + pages={15--28}, + year={1996}, + publisher={Elsevier} + }", + extra_keyword_description = """- `lazy`: determines if the lazy interpolant is used. + """, + extra_keyword_default = "lazy = true") +Base.@kwdef struct BS5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + stage_limiter!::StageLimiter = trivial_limiter! + step_limiter!::StepLimiter = trivial_limiter! + thread::Thread = False() + lazy::Bool = true +end +# for backwards compatibility +function BS5(stage_limiter!, step_limiter! = trivial_limiter!; lazy = true) + BS5(stage_limiter!, step_limiter!, False(), lazy) +end + """ Euler - The canonical forward Euler method. Fixed timestep only. """ +struct Euler <: OrdinaryDiffEqAlgorithm end """ KuttaPRK2p5: Parallel Explicit Runge-Kutta Method diff --git a/src/caches/basic_caches.jl b/src/caches/basic_caches.jl index 45f7564cb6..b5dd5edb7a 100644 --- a/src/caches/basic_caches.jl +++ b/src/caches/basic_caches.jl @@ -100,5 +100,90 @@ end alg_cache(alg::OrdinaryDiffEqAlgorithm, prob, callback::F) where {F} = ODEEmptyCache() +@cache struct FunctionMapCache{uType, rateType} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::rateType +end + +function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + FunctionMapCache(u, uprev, + FunctionMap_scale_by_time(alg) ? rate_prototype : + (eltype(u) <: Enum ? copy(u) : zero(u))) +end + +struct FunctionMapConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + FunctionMapConstantCache() +end + +@cache struct ExplicitRKCache{uType, rateType, uNoUnitsType, TabType} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + utilde::rateType + atmp::uNoUnitsType + fsalfirst::rateType + fsallast::rateType + kk::Vector{rateType} + tab::TabType +end + +TruncatedStacktraces.@truncate_stacktrace ExplicitRKCache 1 + +function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + kk = Vector{typeof(rate_prototype)}(undef, 0) + for i in 1:(alg.tableau.stages) + push!(kk, zero(rate_prototype)) + end + fsalfirst = kk[1] + if isfsal(alg.tableau) + fsallast = kk[end] + else + fsallast = zero(rate_prototype) + end + utilde = zero(rate_prototype) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tab = ExplicitRKConstantCache(alg.tableau, rate_prototype) + ExplicitRKCache(u, uprev, tmp, utilde, atmp, fsalfirst, fsallast, kk, tab) +end + +struct ExplicitRKConstantCache{MType, VType, KType} <: OrdinaryDiffEqConstantCache + A::MType + c::VType + α::VType + αEEst::VType + stages::Int + kk::KType +end + +function ExplicitRKConstantCache(tableau, rate_prototype) + @unpack A, c, α, αEEst, stages = tableau + A = copy(A') # Transpose A to column major looping + kk = Array{typeof(rate_prototype)}(undef, stages) # Not ks since that's for integrator.opts.dense + αEEst = isempty(αEEst) ? αEEst : α .- αEEst + ExplicitRKConstantCache(A, c, α, αEEst, stages, kk) +end + +function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + ExplicitRKConstantCache(alg.tableau, rate_prototype) +end + get_chunksize(cache::DiffEqBase.DECache) = error("This cache does not have a chunksize.") -get_chunksize(cache::ODEChunkCache{CS}) where {CS} = CS \ No newline at end of file +get_chunksize(cache::ODEChunkCache{CS}) where {CS} = CS diff --git a/src/caches/bdf_caches.jl b/src/caches/bdf_caches.jl new file mode 100644 index 0000000000..78a64c7c7b --- /dev/null +++ b/src/caches/bdf_caches.jl @@ -0,0 +1,658 @@ +@cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: + OrdinaryDiffEqConstantCache + nlsolver::N + eulercache::ImplicitEulerConstantCache + dtₙ₋₁::dtType + fsalfirstprev::rate_prototype +end + +function alg_cache(alg::ABDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 2 // 3, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + eulercache = ImplicitEulerConstantCache(nlsolver) + + dtₙ₋₁ = one(dt) + fsalfirstprev = rate_prototype + + ABDF2ConstantCache(nlsolver, eulercache, dtₙ₋₁, fsalfirstprev) +end + +@cache mutable struct ABDF2Cache{uType, rateType, uNoUnitsType, N, dtType, StepLimiter} <: + OrdinaryDiffEqMutableCache + uₙ::uType + uₙ₋₁::uType + uₙ₋₂::uType + fsalfirst::rateType + fsalfirstprev::rateType + zₙ₋₁::uType + atmp::uNoUnitsType + nlsolver::N + eulercache::ImplicitEulerCache + dtₙ₋₁::dtType + step_limiter!::StepLimiter +end + +function alg_cache(alg::ABDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 2 // 3, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + fsalfirstprev = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + algebraic_vars = f.mass_matrix === I ? nothing : + [all(iszero, x) for x in eachcol(f.mass_matrix)] + + eulercache = ImplicitEulerCache( + u, uprev, uprev2, fsalfirst, atmp, nlsolver, algebraic_vars, alg.step_limiter!) + + dtₙ₋₁ = one(dt) + zₙ₋₁ = zero(u) + + ABDF2Cache(u, uprev, uprev2, fsalfirst, fsalfirstprev, zₙ₋₁, atmp, + nlsolver, eulercache, dtₙ₋₁, alg.step_limiter!) +end + +# SBDF + +@cache mutable struct SBDFConstantCache{rateType, N, uType} <: OrdinaryDiffEqConstantCache + cnt::Int + ark::Bool + k2::rateType + nlsolver::N + uprev2::uType + uprev4::uType + uprev3::uType + k₁::rateType + k₂::rateType + k₃::rateType + du₁::rateType + du₂::rateType +end + +@cache mutable struct SBDFCache{uType, rateType, N} <: OrdinaryDiffEqMutableCache + cnt::Int + ark::Bool + u::uType + uprev::uType + fsalfirst::rateType + nlsolver::N + uprev2::uType + uprev3::uType + uprev4::uType + k₁::rateType + k₂::rateType + k₃::rateType + du₁::rateType + du₂::rateType +end + +function alg_cache(alg::SBDF, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + k2 = rate_prototype + k₁ = rate_prototype + k₂ = rate_prototype + k₃ = rate_prototype + du₁ = rate_prototype + du₂ = rate_prototype + + uprev2 = u + uprev3 = u + uprev4 = u + + SBDFConstantCache(1, alg.ark, k2, nlsolver, uprev2, uprev3, uprev4, k₁, k₂, k₃, du₁, + du₂) +end + +function alg_cache(alg::SBDF, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + order = alg.order + + k₁ = zero(rate_prototype) + k₂ = order >= 3 ? zero(rate_prototype) : k₁ + k₃ = order == 4 ? zero(rate_prototype) : k₁ + du₁ = zero(rate_prototype) + du₂ = zero(rate_prototype) + + uprev2 = zero(u) + uprev3 = order >= 3 ? zero(u) : uprev2 + uprev4 = order == 4 ? zero(u) : uprev2 + + SBDFCache( + 1, alg.ark, u, uprev, fsalfirst, nlsolver, uprev2, uprev3, uprev4, k₁, k₂, k₃, + du₁, du₂) +end + +# QNDF1 + +@cache mutable struct QNDF1ConstantCache{ + N, + coefType, + coefType1, + coefType2, + dtType, + uType +} <: OrdinaryDiffEqConstantCache + nlsolver::N + D::coefType1 + D2::coefType2 + R::coefType + U::coefType + uprev2::uType + dtₙ₋₁::dtType +end + +@cache mutable struct QNDF1Cache{uType, rateType, coefType, coefType1, coefType2, + uNoUnitsType, N, dtType, StepLimiter} <: OrdinaryDiffEqMutableCache + uprev2::uType + fsalfirst::rateType + D::coefType1 + D2::coefType2 + R::coefType + U::coefType + atmp::uNoUnitsType + utilde::uType + nlsolver::N + dtₙ₋₁::dtType + step_limiter!::StepLimiter +end + +function alg_cache(alg::QNDF1, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = zero(inv((1 - alg.kappa))), 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + uprev2 = u + dtₙ₋₁ = zero(t) + + D = fill(zero(u), 1, 1) + D2 = fill(zero(u), 1, 2) + R = fill(zero(t), 1, 1) + U = fill(zero(t), 1, 1) + + U!(1, U) + + QNDF1ConstantCache(nlsolver, D, D2, R, U, uprev2, dtₙ₋₁) +end + +function alg_cache(alg::QNDF1, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = zero(inv((1 - alg.kappa))), 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + D = Array{typeof(u)}(undef, 1, 1) + D2 = Array{typeof(u)}(undef, 1, 2) + + R = fill(zero(t), 1, 1) + U = fill(zero(t), 1, 1) + + D[1] = zero(u) + D2[1] = zero(u) + D2[2] = zero(u) + + U!(1, U) + + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + utilde = zero(u) + uprev2 = zero(u) + dtₙ₋₁ = zero(dt) + + QNDF1Cache( + uprev2, fsalfirst, D, D2, R, U, atmp, utilde, nlsolver, dtₙ₋₁, alg.step_limiter!) +end + +# QNDF2 + +@cache mutable struct QNDF2ConstantCache{ + N, + coefType, + coefType1, + coefType2, + uType, + dtType +} <: OrdinaryDiffEqConstantCache + nlsolver::N + D::coefType1 + D2::coefType2 + R::coefType + U::coefType + uprev2::uType + uprev3::uType + dtₙ₋₁::dtType + dtₙ₋₂::dtType +end + +@cache mutable struct QNDF2Cache{uType, rateType, coefType, coefType1, coefType2, + uNoUnitsType, N, dtType, StepLimiter} <: OrdinaryDiffEqMutableCache + uprev2::uType + uprev3::uType + fsalfirst::rateType + D::coefType1 + D2::coefType2 + R::coefType + U::coefType + atmp::uNoUnitsType + utilde::uType + nlsolver::N + dtₙ₋₁::dtType + dtₙ₋₂::dtType + step_limiter!::StepLimiter +end + +function alg_cache(alg::QNDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = zero(inv((1 - alg.kappa))), 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + uprev2 = u + uprev3 = u + dtₙ₋₁ = zero(t) + dtₙ₋₂ = zero(t) + + D = fill(zero(u), 1, 2) + D2 = fill(zero(u), 1, 3) + R = fill(zero(t), 2, 2) + U = fill(zero(t), 2, 2) + + U!(2, U) + + QNDF2ConstantCache(nlsolver, D, D2, R, U, uprev2, uprev3, dtₙ₋₁, dtₙ₋₂) +end + +function alg_cache(alg::QNDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = zero(inv((1 - alg.kappa))), 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + D = Array{typeof(u)}(undef, 1, 2) + D2 = Array{typeof(u)}(undef, 1, 3) + R = fill(zero(t), 2, 2) + U = fill(zero(t), 2, 2) + + D[1] = zero(u) + D[2] = zero(u) + D2[1] = zero(u) + D2[2] = zero(u) + D2[3] = zero(u) + + U!(2, U) + + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + utilde = zero(u) + uprev2 = zero(u) + uprev3 = zero(u) + dtₙ₋₁ = zero(dt) + dtₙ₋₂ = zero(dt) + + QNDF2Cache(uprev2, uprev3, fsalfirst, D, D2, R, U, atmp, + utilde, nlsolver, dtₙ₋₁, dtₙ₋₂, alg.step_limiter!) +end + +@cache mutable struct QNDFConstantCache{ + MO, + N, + coefType, + UType, + dtType, + EEstType, + gammaType +} <: OrdinaryDiffEqConstantCache + nlsolver::N + U::UType + D::coefType + prevD::coefType + prevorder::Int + order::Int + max_order::Val{MO} + dtprev::dtType + nconsteps::Int ##Successful Consecutive Step with the same step size + consfailcnt::Int #Consecutive failed steps count + EEst1::EEstType #Error Estimator for k-1 order + EEst2::EEstType #Error Estimator for k+1 order + γₖ::gammaType +end + +function alg_cache(alg::QNDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits +} where {MO} + max_order = MO + γ, c = one(eltype(alg.kappa)), 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + dtprev = one(dt) + D = Matrix{uEltypeNoUnits}(undef, length(u), max_order + 2) + recursivefill!(D, zero(uEltypeNoUnits)) + prevD = similar(D) + recursivefill!(prevD, zero(uEltypeNoUnits)) + EEst1 = tTypeNoUnits(1) + EEst2 = tTypeNoUnits(1) + + U = zero(MMatrix{max_order, max_order, tTypeNoUnits}) + for r in 1:max_order + U[1, r] = -r + for j in 2:max_order + U[j, r] = U[j - 1, r] * ((j - 1) - r) / j + end + end + U = SArray(U) + + γₖ = SVector(ntuple(k -> sum(tTypeNoUnits(1 // j) for j in 1:k), Val(max_order))) + + QNDFConstantCache(nlsolver, U, D, prevD, 1, 1, Val(max_order), dtprev, 0, 0, EEst1, + EEst2, γₖ) +end + +@cache mutable struct QNDFCache{MO, UType, RUType, rateType, N, coefType, dtType, EEstType, + gammaType, uType, uNoUnitsType, StepLimiter} <: + OrdinaryDiffEqMutableCache + fsalfirst::rateType + dd::uType + utilde::uType + utildem1::uType + utildep1::uType + ϕ::uType + u₀::uType + nlsolver::N + U::UType + RU::RUType + D::coefType + Dtmp::coefType + tmp2::uType + prevD::coefType + order::Int + prevorder::Int + max_order::Val{MO} + dtprev::dtType + nconsteps::Int ##Successful consecutive step with the same step size + consfailcnt::Int #Consecutive failed steps count + EEst1::EEstType #Error Estimator for k-1 order + EEst2::EEstType #Error Estimator for k+1 order + γₖ::gammaType + atmp::uNoUnitsType + atmpm1::uNoUnitsType + atmpp1::uNoUnitsType + step_limiter!::StepLimiter +end + +TruncatedStacktraces.@truncate_stacktrace QNDFCache 1 + +function alg_cache(alg::QNDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits +} where {MO} + max_order = MO + γ, c = one(eltype(alg.kappa)), 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + dd = zero(u) + utilde = zero(u) + utildem1 = zero(u) + utildep1 = zero(u) + ϕ = zero(u) + u₀ = zero(u) + dtprev = one(dt) + D = similar(u, uEltypeNoUnits, length(u), max_order + 2) + recursivefill!(D, zero(uEltypeNoUnits)) + Dtmp = similar(D) + recursivefill!(Dtmp, zero(uEltypeNoUnits)) + prevD = zero(similar(D)) + atmp = zero(similar(u, uEltypeNoUnits)) + atmpm1 = zero(similar(u, uEltypeNoUnits)) + atmpp1 = zero(similar(u, uEltypeNoUnits)) + tmp2 = zero(u) + EEst1 = tTypeNoUnits(1) + EEst2 = tTypeNoUnits(1) + + U = zero(MMatrix{max_order, max_order, tTypeNoUnits}) + for r in 1:max_order + U[1, r] = -r + for j in 2:max_order + U[j, r] = U[j - 1, r] * ((j - 1) - r) / j + end + end + U = SArray(U) + + RU = Matrix(U) + γₖ = SVector(ntuple(k -> sum(tTypeNoUnits(1 // j) for j in 1:k), Val(max_order))) + + QNDFCache(fsalfirst, dd, utilde, utildem1, utildep1, ϕ, u₀, nlsolver, U, RU, D, Dtmp, + tmp2, prevD, 1, 1, Val(max_order), dtprev, 0, 0, EEst1, EEst2, γₖ, atmp, + atmpm1, atmpp1, alg.step_limiter!) +end + +@cache mutable struct MEBDF2Cache{uType, rateType, uNoUnitsType, N} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + uprev2::uType + fsalfirst::rateType + z₁::uType + z₂::uType + tmp2::uType + atmp::uNoUnitsType + nlsolver::N +end + +function alg_cache(alg::MEBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + tmp2 = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + MEBDF2Cache(u, uprev, uprev2, fsalfirst, z₁, z₂, tmp2, atmp, nlsolver) +end + +mutable struct MEBDF2ConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + +function alg_cache(alg::MEBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + MEBDF2ConstantCache(nlsolver) +end + +@cache mutable struct FBDFConstantCache{MO, N, tsType, tType, uType, uuType, coeffType, + EEstType, rType, wType} <: + OrdinaryDiffEqConstantCache + nlsolver::N + ts::tsType + ts_tmp::tsType + t_old::tType + u_history::uuType + order::Int + prev_order::Int + u_corrector::uType + bdf_coeffs::coeffType + max_order::Val{MO} + nconsteps::Int # consecutive success steps + consfailcnt::Int #consecutive failed step counts + terkm2::EEstType + terkm1::EEstType + terk::EEstType + terkp1::EEstType + r::rType + weights::wType + iters_from_event::Int +end + +function alg_cache(alg::FBDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits +} where {MO} + γ, c = 1.0, 1.0 + max_order = MO + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + bdf_coeffs = SA[1 -1 0 0 0 0; + 3//2 -2 1//2 0 0 0; + 11//6 -3 3//2 -1//3 0 0; + 25//12 -4 3 -4//3 1//4 0; + 137//60 -5 5 -10//3 5//4 -1//5] + ts = zero(Vector{typeof(t)}(undef, max_order + 2)) #ts is the successful past points, it will be updated after successful step + ts_tmp = similar(ts) + + u_history = zero(Matrix{eltype(u)}(undef, length(u), max_order + 2)) + order = 1 + prev_order = 1 + u_corrector = similar(u_history) + recursivefill!(u_corrector, zero(eltype(u))) + recursivefill!(u_history, zero(eltype(u_history))) + terkm2 = tTypeNoUnits(1) + terkm1 = tTypeNoUnits(1) + terk = tTypeNoUnits(1) + terkp1 = tTypeNoUnits(1) + r = zero(Vector{typeof(t)}(undef, max_order + 2)) + weights = zero(Vector{typeof(t)}(undef, max_order + 2)) + weights[1] = 1 + nconsteps = 0 + consfailcnt = 0 + t_old = zero(t) + iters_from_event = 0 + + FBDFConstantCache(nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, + u_corrector, bdf_coeffs, Val(5), nconsteps, consfailcnt, terkm2, + terkm1, terk, terkp1, r, weights, iters_from_event) +end + +@cache mutable struct FBDFCache{ + MO, N, rateType, uNoUnitsType, tsType, tType, uType, uuType, + coeffType, EEstType, rType, wType, StepLimiter} <: + OrdinaryDiffEqMutableCache + fsalfirst::rateType + nlsolver::N + ts::tsType + ts_tmp::tsType + t_old::tType + u_history::uuType + order::Int + prev_order::Int + u_corrector::uuType + u₀::uType + bdf_coeffs::coeffType + max_order::Val{MO} + nconsteps::Int # consecutive success steps + consfailcnt::Int #consecutive failed step counts + tmp::uType + atmp::uNoUnitsType + terkm2::EEstType + terkm1::EEstType + terk::EEstType #terk corresponds to hᵏyᵏ(tₙ₊₁) + terkp1::EEstType + terk_tmp::uType + terkp1_tmp::uType + r::rType + weights::wType #weights of Lagrangian formula + equi_ts::tsType + iters_from_event::Int + step_limiter!::StepLimiter +end + +TruncatedStacktraces.@truncate_stacktrace FBDFCache 1 + +function alg_cache(alg::FBDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {MO, uEltypeNoUnits, uBottomEltypeNoUnits, + tTypeNoUnits} + γ, c = 1.0, 1.0 + fsalfirst = zero(rate_prototype) + max_order = MO + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + bdf_coeffs = SA[1 -1 0 0 0 0; + 3//2 -2 1//2 0 0 0; + 11//6 -3 3//2 -1//3 0 0; + 25//12 -4 3 -4//3 1//4 0; + 137//60 -5 5 -10//3 5//4 -1//5] + ts = Vector{typeof(t)}(undef, max_order + 2) #ts is the successful past points, it will be updated after successful step + u_history = Matrix{eltype(u)}(undef, length(u), max_order + 2) + order = 1 + prev_order = 1 + u_corrector = similar(u_history) + recursivefill!(ts, zero(t)) + recursivefill!(u_corrector, zero(eltype(u))) + recursivefill!(u_history, zero(eltype(u_history))) + terkm2 = tTypeNoUnits(1) + terkm1 = tTypeNoUnits(1) + terk = tTypeNoUnits(1) + terkp1 = tTypeNoUnits(1) + terk_tmp = similar(u) + terkp1_tmp = similar(u) + r = Vector{typeof(t)}(undef, max_order + 2) + weights = Vector{typeof(t)}(undef, max_order + 2) + recursivefill!(r, zero(t)) + recursivefill!(weights, zero(t)) + weights[1] = 1 + nconsteps = 0 + consfailcnt = 0 + t_old = zero(t) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, zero(uEltypeNoUnits)) + u₀ = similar(u) + equi_ts = similar(ts) + tmp = similar(u) + ts_tmp = similar(ts) + iters_from_event = 0 + + FBDFCache(fsalfirst, nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, + u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, + terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, + iters_from_event, alg.step_limiter!) +end diff --git a/src/caches/firk_caches.jl b/src/caches/firk_caches.jl new file mode 100644 index 0000000000..f294ad9798 --- /dev/null +++ b/src/caches/firk_caches.jl @@ -0,0 +1,275 @@ +mutable struct RadauIIA3ConstantCache{F, Tab, Tol, Dt, U, JType} <: + OrdinaryDiffEqConstantCache + uf::F + tab::Tab + κ::Tol + ηold::Tol + iter::Int + cont1::U + cont2::U + cont3::U + dtprev::Dt + W_γdt::Dt + status::NLStatus + J::JType +end + +function alg_cache(alg::RadauIIA3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + uf = UDerivativeWrapper(f, t, p) + uToltype = constvalue(uBottomEltypeNoUnits) + tab = RadauIIA3Tableau(uToltype, constvalue(tTypeNoUnits)) + + κ = convert(uToltype, 1 // 100) + J = false .* _vec(rate_prototype) .* _vec(rate_prototype)' + + RadauIIA3ConstantCache(uf, tab, κ, one(uToltype), 10000, u, u, u, dt, dt, + Convergence, J) +end + +mutable struct RadauIIA3Cache{uType, cuType, uNoUnitsType, rateType, JType, W1Type, UF, JC, + F1, Tab, Tol, Dt, rTol, aTol, StepLimiter} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + z1::uType + z2::uType + w1::uType + w2::uType + dw12::cuType + cubuff::cuType + cont1::uType + cont2::uType + du1::rateType + fsalfirst::rateType + k::rateType + k2::rateType + fw1::rateType + fw2::rateType + J::JType + W1::W1Type + uf::UF + tab::Tab + κ::Tol + ηold::Tol + iter::Int + tmp::uType + atmp::uNoUnitsType + jac_config::JC + linsolve::F1 + rtol::rTol + atol::aTol + dtprev::Dt + W_γdt::Dt + status::NLStatus + step_limiter!::StepLimiter +end + +function alg_cache(alg::RadauIIA3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + uf = UJacobianWrapper(f, t, p) + uToltype = constvalue(uBottomEltypeNoUnits) + tab = RadauIIA3Tableau(uToltype, constvalue(tTypeNoUnits)) + + κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) + + z1 = zero(u) + z2 = zero(u) + w1 = zero(u) + w2 = zero(u) + dw12 = similar(u, Complex{eltype(u)}) + recursivefill!(dw12, false) + cubuff = similar(u, Complex{eltype(u)}) + recursivefill!(cubuff, false) + cont1 = zero(u) + cont2 = zero(u) + + fsalfirst = zero(rate_prototype) + k = zero(rate_prototype) + k2 = zero(rate_prototype) + fw1 = zero(rate_prototype) + fw2 = zero(rate_prototype) + + J, W1 = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + W1 = similar(J, Complex{eltype(W1)}) + recursivefill!(W1, false) + + du1 = zero(rate_prototype) + + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + jac_config = jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, dw12) + + linprob = LinearProblem(W1, _vec(cubuff); u0 = _vec(dw12)) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + assumptions = LinearSolve.OperatorAssumptions(true)) + #Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), + #Pr = Diagonal(_vec(weight))) + + rtol = reltol isa Number ? reltol : zero(reltol) + atol = reltol isa Number ? reltol : zero(reltol) + + RadauIIA3Cache(u, uprev, + z1, z2, w1, w2, + dw12, cubuff, cont1, cont2, + du1, fsalfirst, k, k2, fw1, fw2, + J, W1, + uf, tab, κ, one(uToltype), 10000, + tmp, atmp, jac_config, linsolve, rtol, atol, dt, dt, + Convergence, alg.step_limiter!) +end + +mutable struct RadauIIA5ConstantCache{F, Tab, Tol, Dt, U, JType} <: + OrdinaryDiffEqConstantCache + uf::F + tab::Tab + κ::Tol + ηold::Tol + iter::Int + cont1::U + cont2::U + cont3::U + dtprev::Dt + W_γdt::Dt + status::NLStatus + J::JType +end + +function alg_cache(alg::RadauIIA5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + uf = UDerivativeWrapper(f, t, p) + uToltype = constvalue(uBottomEltypeNoUnits) + tab = RadauIIA5Tableau(uToltype, constvalue(tTypeNoUnits)) + + κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) + J = false .* _vec(rate_prototype) .* _vec(rate_prototype)' + + RadauIIA5ConstantCache(uf, tab, κ, one(uToltype), 10000, u, u, u, dt, dt, + Convergence, J) +end + +mutable struct RadauIIA5Cache{uType, cuType, uNoUnitsType, rateType, JType, W1Type, W2Type, + UF, JC, F1, F2, Tab, Tol, Dt, rTol, aTol, StepLimiter} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + z1::uType + z2::uType + z3::uType + w1::uType + w2::uType + w3::uType + dw1::uType + ubuff::uType + dw23::cuType + cubuff::cuType + cont1::uType + cont2::uType + cont3::uType + du1::rateType + fsalfirst::rateType + k::rateType + k2::rateType + k3::rateType + fw1::rateType + fw2::rateType + fw3::rateType + J::JType + W1::W1Type + W2::W2Type # complex + uf::UF + tab::Tab + κ::Tol + ηold::Tol + iter::Int + tmp::uType + atmp::uNoUnitsType + jac_config::JC + linsolve1::F1 + linsolve2::F2 + rtol::rTol + atol::aTol + dtprev::Dt + W_γdt::Dt + status::NLStatus + step_limiter!::StepLimiter +end +TruncatedStacktraces.@truncate_stacktrace RadauIIA5Cache 1 + +function alg_cache(alg::RadauIIA5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + uf = UJacobianWrapper(f, t, p) + uToltype = constvalue(uBottomEltypeNoUnits) + tab = RadauIIA5Tableau(uToltype, constvalue(tTypeNoUnits)) + + κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) + + z1 = zero(u) + z2 = zero(u) + z3 = zero(u) + w1 = zero(u) + w2 = zero(u) + w3 = zero(u) + dw1 = zero(u) + ubuff = zero(u) + dw23 = similar(u, Complex{eltype(u)}) + recursivefill!(dw23, false) + cubuff = similar(u, Complex{eltype(u)}) + recursivefill!(cubuff, false) + cont1 = zero(u) + cont2 = zero(u) + cont3 = zero(u) + + fsalfirst = zero(rate_prototype) + k = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + fw1 = zero(rate_prototype) + fw2 = zero(rate_prototype) + fw3 = zero(rate_prototype) + + J, W1 = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + if J isa AbstractSciMLOperator + error("Non-concrete Jacobian not yet supported by RadauIIA5.") + end + W2 = similar(J, Complex{eltype(W1)}) + recursivefill!(W2, false) + + du1 = zero(rate_prototype) + + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, dw1) + + linprob = LinearProblem(W1, _vec(ubuff); u0 = _vec(dw1)) + linsolve1 = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + assumptions = LinearSolve.OperatorAssumptions(true)) + #Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), + #Pr = Diagonal(_vec(weight))) + linprob = LinearProblem(W2, _vec(cubuff); u0 = _vec(dw23)) + linsolve2 = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + assumptions = LinearSolve.OperatorAssumptions(true)) + #Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), + #Pr = Diagonal(_vec(weight))) + + rtol = reltol isa Number ? reltol : zero(reltol) + atol = reltol isa Number ? reltol : zero(reltol) + + RadauIIA5Cache(u, uprev, + z1, z2, z3, w1, w2, w3, + dw1, ubuff, dw23, cubuff, cont1, cont2, cont3, + du1, fsalfirst, k, k2, k3, fw1, fw2, fw3, + J, W1, W2, + uf, tab, κ, one(uToltype), 10000, + tmp, atmp, jac_config, linsolve1, linsolve2, rtol, atol, dt, dt, + Convergence, alg.step_limiter!) +end diff --git a/src/caches/high_order_rk_caches.jl b/src/caches/high_order_rk_caches.jl new file mode 100644 index 0000000000..bfb55ef511 --- /dev/null +++ b/src/caches/high_order_rk_caches.jl @@ -0,0 +1,265 @@ +@cache struct TanYam7Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, + StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + fsalfirst::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + k9::rateType + k10::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + k::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::TanYam7, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = TanYam7ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + k9 = zero(rate_prototype) + k10 = zero(rate_prototype) + utilde = zero(u) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + k = zero(rate_prototype) + TanYam7Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, utilde, tmp, atmp, k, + tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::TanYam7, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + TanYam7ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct DP8Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, + Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + k9::rateType + k10::rateType + k11::rateType + k12::rateType + k13::rateType + k14::rateType + k15::rateType + k16::rateType + kupdate::rateType + udiff::rateType + bspl::rateType + dense_tmp3::rateType + dense_tmp4::rateType + dense_tmp5::rateType + dense_tmp6::rateType + dense_tmp7::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::DP8, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + k9 = zero(rate_prototype) + k10 = zero(rate_prototype) + k11 = zero(rate_prototype) + k12 = zero(rate_prototype) + kupdate = zero(rate_prototype) + utilde = zero(u) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + k13 = zero(rate_prototype) + k14 = zero(rate_prototype) + k15 = zero(rate_prototype) + k16 = zero(rate_prototype) + udiff = zero(rate_prototype) + bspl = zero(rate_prototype) + # dense_tmp1 = udiff + # dense_tmp2 = bspl + dense_tmp3 = zero(rate_prototype) + dense_tmp4 = zero(rate_prototype) + dense_tmp5 = zero(rate_prototype) + dense_tmp6 = zero(rate_prototype) + dense_tmp7 = zero(rate_prototype) + tab = DP8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + DP8Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, + k16, kupdate, + udiff, bspl, dense_tmp3, dense_tmp4, dense_tmp5, dense_tmp6, dense_tmp7, + utilde, tmp, atmp, tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::DP8, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + DP8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct TsitPap8Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, + StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + fsalfirst::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + k9::rateType + k10::rateType + k11::rateType + k12::rateType + k13::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + k::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::TsitPap8, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = TsitPap8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + k9 = zero(rate_prototype) + k10 = zero(rate_prototype) + k11 = zero(rate_prototype) + k12 = zero(rate_prototype) + k13 = zero(rate_prototype) + utilde = zero(u) + k = zero(rate_prototype) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + TsitPap8Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, + tmp, atmp, k, tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::TsitPap8, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + TsitPap8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct PFRK87Cache{ + uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, + Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + fsalfirst::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + k9::rateType + k10::rateType + k11::rateType + k12::rateType + k13::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + k::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::PFRK87, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = PFRK87ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + k9 = zero(rate_prototype) + k10 = zero(rate_prototype) + k11 = zero(rate_prototype) + k12 = zero(rate_prototype) + k13 = zero(rate_prototype) + utilde = zero(u) + k = zero(rate_prototype) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + PFRK87Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, + tmp, atmp, k, tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::PFRK87, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + PFRK87ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end diff --git a/src/caches/kencarp_kvaerno_caches.jl b/src/caches/kencarp_kvaerno_caches.jl new file mode 100644 index 0000000000..e239a42f10 --- /dev/null +++ b/src/caches/kencarp_kvaerno_caches.jl @@ -0,0 +1,642 @@ +mutable struct Kvaerno3ConstantCache{Tab, N} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::Kvaerno3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Kvaerno3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, 2tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + Kvaerno3ConstantCache(nlsolver, tab) +end + +@cache mutable struct Kvaerno3Cache{uType, rateType, uNoUnitsType, Tab, N, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +function alg_cache(alg::Kvaerno3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Kvaerno3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, 2tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + Kvaerno3Cache( + u, uprev, fsalfirst, z₁, z₂, z₃, z₄, atmp, nlsolver, tab, alg.step_limiter!) +end + +@cache mutable struct KenCarp3ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::KenCarp3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + KenCarp3ConstantCache(nlsolver, tab) +end + +@cache mutable struct KenCarp3Cache{ + uType, rateType, uNoUnitsType, N, Tab, kType, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + k1::kType + k2::kType + k3::kType + k4::kType + atmp::uNoUnitsType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +function alg_cache(alg::KenCarp3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + if f isa SplitFunction + k1 = zero(u) + k2 = zero(u) + k3 = zero(u) + k4 = zero(u) + else + k1 = nothing + k2 = nothing + k3 = nothing + k4 = nothing + uf = UJacobianWrapper(f, t, p) + end + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + KenCarp3Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, k1, k2, + k3, k4, atmp, nlsolver, tab, alg.step_limiter!) +end + +@cache mutable struct CFNLIRK3ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::CFNLIRK3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = CFNLIRK3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + CFNLIRK3ConstantCache(nlsolver, tab) +end + +@cache mutable struct CFNLIRK3Cache{uType, rateType, uNoUnitsType, N, Tab, kType} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + k1::kType + k2::kType + k3::kType + k4::kType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::CFNLIRK3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = CFNLIRK3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + k1 = zero(u) + k2 = zero(u) + k3 = zero(u) + k4 = zero(u) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + CFNLIRK3Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, k1, k2, k3, k4, atmp, nlsolver, tab) +end + +@cache mutable struct Kvaerno4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::Kvaerno4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Kvaerno4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + Kvaerno4ConstantCache(nlsolver, tab) +end + +@cache mutable struct Kvaerno4Cache{uType, rateType, uNoUnitsType, N, Tab, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +function alg_cache(alg::Kvaerno4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Kvaerno4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + Kvaerno4Cache( + u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab, alg.step_limiter!) +end + +@cache mutable struct KenCarp4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::KenCarp4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + KenCarp4ConstantCache(nlsolver, tab) +end + +@cache mutable struct KenCarp4Cache{ + uType, rateType, uNoUnitsType, N, Tab, kType, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + k1::kType + k2::kType + k3::kType + k4::kType + k5::kType + k6::kType + atmp::uNoUnitsType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +TruncatedStacktraces.@truncate_stacktrace KenCarp4Cache 1 + +function alg_cache(alg::KenCarp4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + if f isa SplitFunction + k1 = zero(u) + k2 = zero(u) + k3 = zero(u) + k4 = zero(u) + k5 = zero(u) + k6 = zero(u) + else + k1 = nothing + k2 = nothing + k3 = nothing + k4 = nothing + k5 = nothing + k6 = nothing + uf = UJacobianWrapper(f, t, p) + end + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + KenCarp4Cache( + u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, k1, k2, k3, k4, k5, k6, atmp, + nlsolver, tab, alg.step_limiter!) +end + +@cache mutable struct Kvaerno5ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::Kvaerno5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Kvaerno5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + Kvaerno5ConstantCache(nlsolver, tab) +end + +@cache mutable struct Kvaerno5Cache{uType, rateType, uNoUnitsType, N, Tab, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +function alg_cache(alg::Kvaerno5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Kvaerno5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + Kvaerno5Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, + z₇, atmp, nlsolver, tab, alg.step_limiter!) +end + +@cache mutable struct KenCarp5ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::KenCarp5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + KenCarp5ConstantCache(nlsolver, tab) +end + +@cache mutable struct KenCarp5Cache{ + uType, rateType, uNoUnitsType, N, Tab, kType, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + z₈::uType + k1::kType + k2::kType + k3::kType + k4::kType + k5::kType + k6::kType + k7::kType + k8::kType + atmp::uNoUnitsType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +function alg_cache(alg::KenCarp5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + if f isa SplitFunction + k1 = zero(u) + k2 = zero(u) + k3 = zero(u) + k4 = zero(u) + k5 = zero(u) + k6 = zero(u) + k7 = zero(u) + k8 = zero(u) + else + k1 = nothing + k2 = nothing + k3 = nothing + k4 = nothing + k5 = nothing + k6 = nothing + k7 = nothing + k8 = nothing + end + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = zero(u) + z₈ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + KenCarp5Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, + k1, k2, k3, k4, k5, k6, k7, k8, atmp, nlsolver, tab, alg.step_limiter!) +end + +@cache mutable struct KenCarp47ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::KenCarp47, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp47Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + KenCarp47ConstantCache(nlsolver, tab) +end + +@cache mutable struct KenCarp47Cache{uType, rateType, uNoUnitsType, N, Tab, kType} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + k1::kType + k2::kType + k3::kType + k4::kType + k5::kType + k6::kType + k7::kType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end +TruncatedStacktraces.@truncate_stacktrace KenCarp47Cache 1 + +function alg_cache(alg::KenCarp47, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp47Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + if f isa SplitFunction + k1 = zero(u) + k2 = zero(u) + k3 = zero(u) + k4 = zero(u) + k5 = zero(u) + k6 = zero(u) + k7 = zero(u) + else + k1 = nothing + k2 = nothing + k3 = nothing + k4 = nothing + k5 = nothing + k6 = nothing + k7 = nothing + end + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + KenCarp47Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, + k1, k2, k3, k4, k5, k6, k7, atmp, nlsolver, tab) +end + +@cache mutable struct KenCarp58ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::KenCarp58, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp58Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + KenCarp58ConstantCache(nlsolver, tab) +end + +@cache mutable struct KenCarp58Cache{uType, rateType, uNoUnitsType, N, Tab, kType} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + z₈::uType + k1::kType + k2::kType + k3::kType + k4::kType + k5::kType + k6::kType + k7::kType + k8::kType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +TruncatedStacktraces.@truncate_stacktrace KenCarp58Cache 1 + +function alg_cache(alg::KenCarp58, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = KenCarp58Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.c3 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + if f isa SplitFunction + k1 = zero(u) + k2 = zero(u) + k3 = zero(u) + k4 = zero(u) + k5 = zero(u) + k6 = zero(u) + k7 = zero(u) + k8 = zero(u) + else + k1 = nothing + k2 = nothing + k3 = nothing + k4 = nothing + k5 = nothing + k6 = nothing + k7 = nothing + k8 = nothing + end + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = zero(u) + z₈ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + KenCarp58Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, + k1, k2, k3, k4, k5, k6, k7, k8, atmp, nlsolver, tab) +end diff --git a/src/caches/low_order_rk_caches.jl b/src/caches/low_order_rk_caches.jl new file mode 100644 index 0000000000..0da22a8f41 --- /dev/null +++ b/src/caches/low_order_rk_caches.jl @@ -0,0 +1,1537 @@ +@cache struct EulerCache{uType, rateType} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + k::rateType + fsalfirst::rateType +end + +@cache struct SplitEulerCache{uType, rateType} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + k::rateType + fsalfirst::rateType +end + +function alg_cache(alg::SplitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + SplitEulerCache(u, uprev, zero(u), zero(rate_prototype), zero(rate_prototype)) +end + +struct SplitEulerConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::SplitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + SplitEulerConstantCache() +end + +function alg_cache(alg::Euler, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + EulerCache(u, uprev, zero(u), zero(rate_prototype), zero(rate_prototype)) +end + +struct EulerConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::Euler, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + EulerConstantCache() +end + +@cache struct HeunCache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + atmp::uNoUnitsType + k::rateType + fsalfirst::rateType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +@cache struct RalstonCache{ + uType, + rateType, + uNoUnitsType, + StageLimiter, + StepLimiter, + Thread +} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + atmp::uNoUnitsType + k::rateType + fsalfirst::rateType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::Heun, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + HeunCache(u, uprev, zero(u), atmp, zero(rate_prototype), + zero(rate_prototype), alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::Ralston, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + RalstonCache(u, uprev, zero(u), atmp, zero(rate_prototype), + zero(rate_prototype), alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +struct HeunConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::Heun, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + HeunConstantCache() +end + +struct RalstonConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::Ralston, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + RalstonConstantCache() +end + +@cache struct MidpointCache{ + uType, + rateType, + uNoUnitsType, + StageLimiter, + StepLimiter, + Thread +} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k::rateType + tmp::uType + atmp::uNoUnitsType + fsalfirst::rateType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +struct MidpointConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::Midpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + k = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + MidpointCache(u, uprev, k, tmp, atmp, fsalfirst, alg.stage_limiter!, alg.step_limiter!, + alg.thread) +end + +function alg_cache(alg::Midpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + MidpointConstantCache() +end + +@cache struct RK4Cache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + fsalfirst::rateType + k₂::rateType + k₃::rateType + k₄::rateType + k::rateType + tmp::uType + atmp::uNoUnitsType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +struct RK4ConstantCache <: OrdinaryDiffEqConstantCache end + +function alg_cache(alg::RK4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k₁ = zero(rate_prototype) + k₂ = zero(rate_prototype) + k₃ = zero(rate_prototype) + k₄ = zero(rate_prototype) + k = zero(rate_prototype) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + RK4Cache(u, uprev, k₁, k₂, k₃, k₄, k, tmp, atmp, alg.stage_limiter!, alg.step_limiter!, + alg.thread) +end + +function alg_cache(alg::RK4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + RK4ConstantCache() +end + +@cache struct BS3Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, + Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + fsalfirst::rateType + k2::rateType + k3::rateType + k4::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::BS3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = BS3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + BS3Cache(u, uprev, k1, k2, k3, k4, utilde, tmp, atmp, tab, alg.stage_limiter!, + alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::BS3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + BS3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct OwrenZen3Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, + StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::OwrenZen3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = OwrenZen3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + OwrenZen3Cache(u, uprev, k1, k2, k3, k4, utilde, tmp, atmp, tab, alg.stage_limiter!, + alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::OwrenZen3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + OwrenZen3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct OwrenZen4Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, + StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::OwrenZen4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = OwrenZen4ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + OwrenZen4Cache(u, uprev, k1, k2, k3, k4, k5, k6, utilde, tmp, atmp, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::OwrenZen4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + OwrenZen4ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct OwrenZen5Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, + StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::OwrenZen5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = OwrenZen5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + OwrenZen5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::OwrenZen5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + OwrenZen5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct BS5Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, + Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::BS5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = BS5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + BS5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +function alg_cache(alg::BS5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + BS5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct Tsit5Cache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, + Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end +if isdefined(Base, :Experimental) && isdefined(Base.Experimental, :silence!) + Base.Experimental.silence!(Tsit5Cache) +end + +function alg_cache(alg::Tsit5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + Tsit5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +TruncatedStacktraces.@truncate_stacktrace Tsit5Cache 1 + +function alg_cache(alg::Tsit5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + Tsit5ConstantCache() +end + +@cache struct DP5Cache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, + Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + dense_tmp3::rateType + dense_tmp4::rateType + update::rateType + bspl::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::DP5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = k2 + k7 = zero(rate_prototype) # This is FSAL'd to k1 + dense_tmp3 = k2 + dense_tmp4 = k5 + bspl = k3 + + tmp = zero(u) # has to be separate for FSAL + utilde = tmp + + if eltype(u) != uEltypeNoUnits || calck + update = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + else + update = k7 + atmp = k3 + end + + cache = DP5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, dense_tmp3, dense_tmp4, update, + bspl, utilde, tmp, atmp, alg.stage_limiter!, alg.step_limiter!, + alg.thread) + cache +end + +function alg_cache(alg::DP5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + DP5ConstantCache() +end + +@cache struct Anas5Cache{ + uType, + rateType, + uNoUnitsType, + TabType, + StageLimiter, + StepLimiter, + Thread +} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::Anas5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Anas5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + Anas5Cache(u, + uprev, + k1, + k2, + k3, + k4, + k5, + k6, + k7, + utilde, + tmp, + atmp, + tab, + alg.stage_limiter!, + alg.step_limiter!, + alg.thread) +end + +function alg_cache(alg::Anas5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + Anas5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +@cache struct RKO65Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + tmp::uType + fsalfirst::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +u_cache(c::RKO65Cache) = () +du_cache(c::RKO65Cache) = (c.k, c.du, c.fsalfirst) + +struct RKO65ConstantCache{T1, T2} <: OrdinaryDiffEqConstantCache + α21::T1 + α31::T1 + α41::T1 + α51::T1 + + α32::T1 + α42::T1 + α52::T1 + α62::T1 + + α43::T1 + α53::T1 + α63::T1 + + α54::T1 + α64::T1 + + α65::T1 + + β2::T1 + β3::T1 + β4::T1 + β5::T1 + β6::T1 + + c1::T2 + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + + function RKO65ConstantCache(T1, T2) + # elements of Butcher Table + α21 = T1(1 // 6) + α31 = T1(-15 // 8) + α41 = T1(-9 // 1) + α51 = T1(-3 // 1) + + α32 = T1(21 // 8) + α42 = T1(75 // 7) + α52 = T1(34257 // 8750) + α62 = T1(123 // 380) + + α43 = T1(-5 // 7) + α53 = T1(-114 // 875) + α63 = T1(5 // 2) + + α54 = T1(19 // 1250) + α64 = T1(3 // 20) + + α65 = T1(-75 // 38) + + β2 = T1(54 // 133) + β3 = T1(32 // 21) + β4 = T1(1 // 18) + β5 = T1(-125 // 114) + β6 = T1(1 // 9) + + c1 = T2(2 // 3) + c2 = T2(1 // 6) + c3 = T2(3 // 4) + c4 = T2(1 // 1) + c5 = T2(4 // 5) + c6 = T2(1 // 1) + new{T1, T2}(α21, α31, α41, α51, α32, α42, α52, α62, α43, α53, α63, α54, α64, α65, + β2, β3, β4, β5, β6, c1, c2, c3, c4, c5, c6) + end +end + +function alg_cache(alg::RKO65, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + RKO65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) # why not real(tTypeNoUnits)? +end + +function alg_cache(alg::RKO65, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tmp = zero(u) + + k = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + + fsalfirst = zero(rate_prototype) + + tab = RKO65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + RKO65Cache( + u, uprev, k, k1, k2, k3, k4, k5, k6, tmp, fsalfirst, tab, alg.stage_limiter!, + alg.step_limiter!, alg.thread) +end + +@cache struct FRK65Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, + Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + utilde::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + k9::rateType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +struct FRK65ConstantCache{T1, T2} <: OrdinaryDiffEqConstantCache + α21::T1 + α31::T1 + α41::T1 + α51::T1 + α61::T1 + α71::T1 + α81::T1 + α91::T1 + + α32::T1 + + α43::T1 + α53::T1 + α63::T1 + α73::T1 + α83::T1 + + α54::T1 + α64::T1 + α74::T1 + α84::T1 + α94::T1 + + α65::T1 + α75::T1 + α85::T1 + α95::T1 + + α76::T1 + α86::T1 + α96::T1 + + α87::T1 + α97::T1 + + α98::T1 + + β1::T1 + # β4::T1 + # β5::T1 + # β6::T1 + β7::T1 + β8::T1 + + β1tilde::T1 + β4tilde::T1 + β5tilde::T1 + β6tilde::T1 + β7tilde::T1 + β8tilde::T1 + β9tilde::T1 + + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + c8::T2 + c9::T2 + + d1::T1 + d2::T1 + d3::T1 + d4::T1 + d5::T1 + d6::T1 + d7::T1 + d8::T1 + d9::T1 + d10::T1 + d11::T1 + d12::T1 + d13::T1 + + e1::T1 + e2::T1 + e3::T1 + e4::T1 + e5::T1 + e6::T1 + e7::T1 + e8::T1 + e9::T1 + e10::T1 + e11::T1 + + f1::T1 + f2::T1 + f3::T1 + f4::T1 + f5::T1 + f6::T1 + f7::T1 + f8::T1 + f9::T1 + f10::T1 + f11::T1 + + function FRK65ConstantCache(T1, T2) + + # elements of Butcher Table + α21 = T1(1 // 89) + α31 = T1(-38624 // 142129) + α41 = T1(51 // 1508) + α51 = T1(3259284578 // 3517556363) + α61 = T1(-108363632681 // 45875676369) + α71 = T1(7137368591 // 11299833148) + α81 = T1(8898824396 // 9828950919) + α91 = T1(1026331676 // 33222204855) + + α32 = T1(51442 // 142129) + + α43 = T1(153 // 1508) + α53 = T1(-69727055112 // 19553806387) + α63 = T1(80902506271 // 8700424616) + α73 = T1(-33088067061 // 10572251159) + α83 = T1(25673454973 // 11497947835) + + α54 = T1(36230363390 // 11788838981) + α64 = T1(-120088218786 // 17139312481) + α74 = T1(11481363823 // 3650030081) + α84 = T1(-74239028301 // 15737704666) + α94 = T1(1450675392 // 5936579813) + + α65 = T1(4533285649 // 6676940598) + α75 = T1(-4096673444 // 7349814937) + α85 = T1(222688842816 // 44196813415) + α95 = T1(4617877550 // 16762182457) + + α76 = T1(9911918171 // 12847192605) + α86 = T1(-105204445705 // 30575217706) + α96 = T1(1144867463 // 6520294355) + + α87 = T1(8799291910 // 8966990271) + α97 = T1(1822809703 // 7599996644) + + α98 = T1(79524953 // 2351253316) + + β1 = T1(1026331676 // 33222204855) + #β4 = T1(1450675392//5936579813) + #β5 = T1(4617877550//16762182457) + #β6 = T1(1144867463//6520294355) + β7 = T1(1822809703 // 7599996644) + β8 = T1(79524953 // 2351253316) + + β1tilde = T1(413034411 // 13925408836) + β4tilde = T1(1865954212 // 7538591735) + β5tilde = T1(4451980162 // 16576017119) + β6tilde = T1(1157843020 // 6320223511) + β7tilde = T1(802708729 // 3404369569) + β8tilde = T1(-251398161 // 17050111121) + β9tilde = T1(1 // 20) + + c2 = T2(1 // 89) + c3 = T2(34 // 377) + c4 = T2(51 // 377) + c5 = T2(14497158 // 33407747) + c6 = T2(9744566553 // 16002998914) + c7 = T2(330 // 383) + c8 = T2(1 // 1) + c9 = T2(1 // 1) + + d1 = T1(140209127 // 573775965) + d2 = T1(-8530039 // 263747097) + d3 = T1(-308551 // 104235790) + d4 = T1(233511 // 333733259) + d5 = T1(9126 // 184950985) + d6 = T1(22 // 50434083) + d7 = T1(19 // 424427471) + d8 = T1(-28711 // 583216934059) + d9 = T1(-3831531 // 316297807) + d10 = T1(551767 // 187698280) + d11 = T1(9205 // 210998423) + d12 = T1(-250 // 519462673) + d13 = T1(67 // 327513887) + + e1 = T1(437217689 // 1587032700) + e2 = T1(-15824413 // 592362279) + e3 = T1(-1563775 // 341846569) + e4 = T1(270497 // 369611210) + e5 = T1(-26623 // 453099487) + e6 = T1(-616297487849) + e7 = T1(-47682337 // 491732789) + e8 = T1(-4778275 // 287766311) + e9 = T1(641177 // 265376522) + e10 = T1(44633 // 291742143) + e11 = T1(611 // 223639880) + + f1 = T1(44861261 // 255495624) + f2 = T1(-11270940 // 352635157) + f3 = T1(-182222 // 232874507) + f4 = T1(164263 // 307215200) + f5 = T1(32184 // 652060417) + f6 = T1(-352 // 171021903) + f7 = T1(-18395427 // 101056291) + f8 = T1(-621686 // 139501937) + f9 = T1(2030024 // 612171255) + f10 = T1(-711049 // 7105160932) + f11 = T1(267 // 333462710) + + new{T1, T2}(α21, α31, α41, α51, α61, α71, α81, α91, α32, α43, α53, α63, α73, α83, + α54, α64, α74, α84, α94, α65, α75, α85, α95, α76, α86, α96, α87, α97, + α98, β1, β7, β8, β1tilde, β4tilde, β5tilde, β6tilde, β7tilde, β8tilde, + β9tilde, c2, c3, c4, c5, c6, c7, c8, c9, d1, d2, d3, d4, d5, d6, d7, d8, + d9, d10, d11, d12, d13, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, + f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) + end +end + +function alg_cache(alg::FRK65, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + FRK65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::FRK65, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = FRK65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + k9 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + FRK65Cache(u, uprev, utilde, k1, k2, k3, k4, k5, k6, k7, k8, k9, tmp, atmp, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +@cache struct RKMCache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + tmp::uType + fsalfirst::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +struct RKMConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + α2::T + α3::T + α4::T + α5::T + α6::T + β1::T + β2::T + β3::T + β4::T + β6::T + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + + function RKMConstantCache(::Type{T}, ::Type{T2}) where {T, T2} + # α2 = T(0.16791846623918) + # α3 = T(0.48298439719700) + # α4 = T(0.70546072965982) + # α5 = T(0.09295870406537) + # α6 = T(0.76210081248836) + # β1 = T(-0.15108370762927) + # β2 = T(0.75384683913851) + # β3 = T(-0.36016595357907) + # β4 = T(0.52696773139913) + # β6 = T(0.23043509067071) + # c2 = T2(0.16791846623918) + # c3 = T2(0.48298439719700) + # c4 = T2(0.70546072965982) + # c5 = T2(0.09295870406537) + # c6 = T2(0.76210081248836) + + α2 = T(0.167266187050662) + α3 = T(0.484574582244783) + α4 = T(0.536909403373491) + α5 = T(0.082069535961948) + α6 = T(0.853923000035347) + β1 = T(-0.028289441132839) + β2 = T(0.463968918564710) + β3 = T(-0.434414348751899) + β4 = T(0.693796229087598) + β6 = T(0.304938642232430) + c2 = T2(0.167266187050662) + c3 = T2(0.484574582244783) + c4 = T2(0.536909403373491) + c5 = T2(0.082069535961948) + c6 = T2(0.853923000035347) + + new{T, T2}(α2, α3, α4, α5, α6, β1, β2, β3, β4, β6, c2, c3, c4, c5, c6) + end +end + +function alg_cache(alg::RKM, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + RKMConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::RKM, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = RKMConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + k = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + tmp = zero(u) + fsalfirst = zero(rate_prototype) + RKMCache(u, uprev, k, k1, k2, k3, k4, k5, k6, tmp, fsalfirst, tab, alg.stage_limiter!, + alg.step_limiter!, alg.thread) +end + +@cache struct MSRK5Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + fsalfirst::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + k9::rateType + k::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::MSRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return MSRK5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::MSRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + k9 = zero(rate_prototype) + k = zero(rate_prototype) + tmp = zero(u) + fsalfirst = zero(u) + tab = MSRK5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + MSRK5Cache(u, uprev, tmp, fsalfirst, k1, k2, k3, k4, k5, k6, k7, k8, k9, k, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +@cache struct MSRK6Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + fsalfirst::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + k9::rateType + k::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::MSRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return MSRK6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::MSRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + k9 = zero(rate_prototype) + k = zero(rate_prototype) + tmp = zero(u) + fsalfirst = zero(u) + tab = MSRK6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + MSRK6Cache(u, uprev, tmp, fsalfirst, k1, k2, k3, k4, k5, k6, k7, k8, k9, k, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +@cache struct PSRK4p7q6Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + tmp::uType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::PSRK4p7q6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return PSRK4p7q6ConstantCache( + constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::PSRK4p7q6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + tmp = zero(u) + tab = PSRK4p7q6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + PSRK4p7q6Cache(u, uprev, k1, k2, k3, k4, k5, k6, tmp, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +@cache struct PSRK3p6q5Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + tmp::uType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::PSRK3p6q5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return PSRK3p6q5ConstantCache( + constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::PSRK3p6q5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + tmp = zero(u) + tab = PSRK3p6q5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + PSRK3p6q5Cache(u, uprev, tmp, k1, k2, k3, k4, k5, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +@cache struct PSRK3p5q4Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + tmp::uType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::PSRK3p5q4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return PSRK3p5q4ConstantCache( + constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::PSRK3p5q4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + tmp = zero(u) + tab = PSRK3p5q4ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + PSRK3p5q4Cache(u, uprev, tmp, k1, k2, k3, k4, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +@cache struct Stepanov5Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + fsalfirst::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k::rateType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::Stepanov5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return Stepanov5ConstantCache(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::Stepanov5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k = zero(rate_prototype) + tmp = zero(u) + fsalfirst = zero(u) + tab = Stepanov5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + Stepanov5Cache(u, + uprev, + tmp, + fsalfirst, + k1, + k2, + k3, + k4, + k5, + k6, + k7, + k, + tab, + alg.stage_limiter!, + alg.step_limiter!, + alg.thread) +end + +@cache struct SIR54Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, + Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + utilde::uType + tmp::uType + atmp::uNoUnitsType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::SIR54, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return SIR54ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::SIR54, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + utilde = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tmp = zero(u) + tab = SIR54ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + SIR54Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, tab, + alg.stage_limiter!, alg.step_limiter!, alg.thread) +end + +@cache struct Alshina2Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, + StepLimiter, Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + utilde::uType + k1::rateType + k2::rateType + atmp::uNoUnitsType + tmp::uType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::Alshina2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return Alshina2ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::Alshina2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + utilde = zero(u) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tab = Alshina2ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + Alshina2Cache(u, uprev, utilde, k1, k2, atmp, tmp, tab, alg.stage_limiter!, + alg.step_limiter!, alg.thread) +end + +@cache struct Alshina3Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, + StepLimiter, Thread} <: OrdinaryDiffEqMutableCache + u::uType + uprev::uType + utilde::uType + k1::rateType + k2::rateType + k3::rateType + atmp::uNoUnitsType + tmp::uType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::Alshina3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return Alshina3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::Alshina3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + utilde = zero(u) + tmp = zero(u) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + tab = Alshina3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + Alshina3Cache(u, uprev, utilde, k1, k2, k3, atmp, tmp, tab, alg.stage_limiter!, + alg.step_limiter!, alg.thread) +end + +@cache struct Alshina6Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + tmp::uType + tab::TabType + stage_limiter!::StageLimiter + step_limiter!::StepLimiter + thread::Thread +end + +function alg_cache(alg::Alshina6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + return Alshina6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) +end + +function alg_cache(alg::Alshina6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + tmp = zero(u) + tab = Alshina6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + Alshina6Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, tmp, tab, alg.stage_limiter!, + alg.step_limiter!, alg.thread) +end diff --git a/src/caches/rosenbrock_caches.jl b/src/caches/rosenbrock_caches.jl new file mode 100644 index 0000000000..e2eb013809 --- /dev/null +++ b/src/caches/rosenbrock_caches.jl @@ -0,0 +1,1143 @@ +abstract type RosenbrockMutableCache <: OrdinaryDiffEqMutableCache end +################################################################################ + +# Shampine's Low-order Rosenbrocks + +@cache mutable struct Rosenbrock23Cache{uType, rateType, uNoUnitsType, JType, WType, + TabType, TFType, UFType, F, JCType, GCType, + RTolType, A, AV, StepLimiter, StageLimiter} <: RosenbrockMutableCache + u::uType + uprev::uType + k₁::rateType + k₂::rateType + k₃::rateType + du1::rateType + du2::rateType + f₁::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + reltol::RTolType + alg::A + algebraic_vars::AV + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +TruncatedStacktraces.@truncate_stacktrace Rosenbrock23Cache 1 + +@cache mutable struct Rosenbrock32Cache{uType, rateType, uNoUnitsType, JType, WType, + TabType, TFType, UFType, F, JCType, GCType, + RTolType, A, AV, StepLimiter, StageLimiter} <: RosenbrockMutableCache + u::uType + uprev::uType + k₁::rateType + k₂::rateType + k₃::rateType + du1::rateType + du2::rateType + f₁::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + reltol::RTolType + alg::A + algebraic_vars::AV + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +function alg_cache(alg::Rosenbrock23, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k₁ = zero(rate_prototype) + k₂ = zero(rate_prototype) + k₃ = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + # f₀ = zero(u) fsalfirst + f₁ = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rosenbrock23Tableau(constvalue(uBottomEltypeNoUnits)) + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2, Val(false)) + algebraic_vars = f.mass_matrix === I ? nothing : + [all(iszero, x) for x in eachcol(f.mass_matrix)] + + Rosenbrock23Cache(u, uprev, k₁, k₂, k₃, du1, du2, f₁, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, + linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, algebraic_vars, alg.step_limiter!, + alg.stage_limiter!) +end + +function alg_cache(alg::Rosenbrock32, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + k₁ = zero(rate_prototype) + k₂ = zero(rate_prototype) + k₃ = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + # f₀ = zero(u) fsalfirst + f₁ = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rosenbrock32Tableau(constvalue(uBottomEltypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2, Val(false)) + algebraic_vars = f.mass_matrix === I ? nothing : + [all(iszero, x) for x in eachcol(f.mass_matrix)] + + Rosenbrock32Cache(u, uprev, k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, + tmp, atmp, weight, tab, tf, uf, linsolve_tmp, linsolve, jac_config, + grad_config, reltol, alg, algebraic_vars, alg.step_limiter!, alg.stage_limiter!) +end + +struct Rosenbrock23ConstantCache{T, TF, UF, JType, WType, F, AD} <: + OrdinaryDiffEqConstantCache + c₃₂::T + d::T + tf::TF + uf::UF + J::JType + W::WType + linsolve::F + autodiff::AD +end + +function Rosenbrock23ConstantCache(::Type{T}, tf, uf, J, W, linsolve, autodiff) where {T} + tab = Rosenbrock23Tableau(T) + Rosenbrock23ConstantCache(tab.c₃₂, tab.d, tf, uf, J, W, linsolve, autodiff) +end + +function alg_cache(alg::Rosenbrock23, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rosenbrock23ConstantCache(constvalue(uBottomEltypeNoUnits), tf, uf, J, W, linsolve, + alg_autodiff(alg)) +end + +struct Rosenbrock32ConstantCache{T, TF, UF, JType, WType, F, AD} <: + OrdinaryDiffEqConstantCache + c₃₂::T + d::T + tf::TF + uf::UF + J::JType + W::WType + linsolve::F + autodiff::AD +end + +function Rosenbrock32ConstantCache(::Type{T}, tf, uf, J, W, linsolve, autodiff) where {T} + tab = Rosenbrock32Tableau(T) + Rosenbrock32ConstantCache(tab.c₃₂, tab.d, tf, uf, J, W, linsolve, autodiff) +end + +function alg_cache(alg::Rosenbrock32, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rosenbrock32ConstantCache(constvalue(uBottomEltypeNoUnits), tf, uf, J, W, linsolve, + alg_autodiff(alg)) +end + +################################################################################ + +### 3rd order specialized Rosenbrocks + +struct Rosenbrock33ConstantCache{TF, UF, Tab, JType, WType, F} <: + OrdinaryDiffEqConstantCache + tf::TF + uf::UF + tab::Tab + J::JType + W::WType + linsolve::F +end + +@cache mutable struct Rosenbrock33Cache{uType, rateType, uNoUnitsType, JType, WType, + TabType, TFType, UFType, F, JCType, GCType, + RTolType, A, StepLimiter, StageLimiter} <: RosenbrockMutableCache + u::uType + uprev::uType + du::rateType + du1::rateType + du2::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + reltol::RTolType + alg::A + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +function alg_cache(alg::ROS3P, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = ROS3PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rosenbrock33Cache(u, uprev, du, du1, du2, k1, k2, k3, k4, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, + linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +function alg_cache(alg::ROS3P, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rosenbrock33ConstantCache(tf, uf, + ROS3PTableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve) +end + +@cache mutable struct Rosenbrock34Cache{uType, rateType, uNoUnitsType, JType, WType, + TabType, TFType, UFType, F, JCType, GCType, StepLimiter, StageLimiter} <: + RosenbrockMutableCache + u::uType + uprev::uType + du::rateType + du1::rateType + du2::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +function alg_cache(alg::Rodas3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rosenbrock34Cache(u, uprev, du, du1, du2, k1, k2, k3, k4, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, + linsolve_tmp, + linsolve, jac_config, grad_config, alg.step_limiter!, + alg.stage_limiter!) +end + +struct Rosenbrock34ConstantCache{TF, UF, Tab, JType, WType, F} <: + OrdinaryDiffEqConstantCache + tf::TF + uf::UF + tab::Tab + J::JType + W::WType + linsolve::F +end + +function alg_cache(alg::Rodas3, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rosenbrock34ConstantCache(tf, uf, + Rodas3Tableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve) +end + +################################################################################ + +### ROS2 methods + +@ROS2(:cache) + +################################################################################ + +### ROS23 methods + +@ROS23(:cache) + +################################################################################ + +### ROS34PW methods + +@ROS34PW(:cache) + +################################################################################ + +### ROS4 methods + +@Rosenbrock4(:cache) +jac_cache(c::Rosenbrock4Cache) = (c.J, c.W) + +############################################################################### + +### Rodas methods + +struct Rodas23WConstantCache{TF, UF, Tab, JType, WType, F, AD} <: + OrdinaryDiffEqConstantCache + tf::TF + uf::UF + tab::Tab + J::JType + W::WType + linsolve::F + autodiff::AD +end + +struct Rodas3PConstantCache{TF, UF, Tab, JType, WType, F, AD} <: OrdinaryDiffEqConstantCache + tf::TF + uf::UF + tab::Tab + J::JType + W::WType + linsolve::F + autodiff::AD +end + +@cache mutable struct Rodas23WCache{uType, rateType, uNoUnitsType, JType, WType, TabType, + TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: + RosenbrockMutableCache + u::uType + uprev::uType + dense1::rateType + dense2::rateType + dense3::rateType + du::rateType + du1::rateType + du2::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + reltol::RTolType + alg::A + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +@cache mutable struct Rodas3PCache{uType, rateType, uNoUnitsType, JType, WType, TabType, + TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: + RosenbrockMutableCache + u::uType + uprev::uType + dense1::rateType + dense2::rateType + dense3::rateType + du::rateType + du1::rateType + du2::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + reltol::RTolType + alg::A + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +function alg_cache(alg::Rodas23W, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + dense3 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas3PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rodas23WCache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, k5, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace Rodas23WCache 1 +function alg_cache(alg::Rodas3P, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + dense3 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas3PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rodas3PCache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, k5, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace Rodas3PCache 1 + +function alg_cache(alg::Rodas23W, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rodas23WConstantCache(tf, uf, + Rodas3PTableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve, + alg_autodiff(alg)) +end + +function alg_cache(alg::Rodas3P, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rodas3PConstantCache(tf, uf, + Rodas3PTableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve, + alg_autodiff(alg)) +end + +### Rodas4 methods + +struct Rodas4ConstantCache{TF, UF, Tab, JType, WType, F, AD} <: OrdinaryDiffEqConstantCache + tf::TF + uf::UF + tab::Tab + J::JType + W::WType + linsolve::F + autodiff::AD +end + +@cache mutable struct Rodas4Cache{uType, rateType, uNoUnitsType, JType, WType, TabType, + TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: + RosenbrockMutableCache + u::uType + uprev::uType + dense1::rateType + dense2::rateType + du::rateType + du1::rateType + du2::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + reltol::RTolType + alg::A + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +function alg_cache(alg::Rodas4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, + k5, k6, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace Rodas4Cache 1 + +function alg_cache(alg::Rodas4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rodas4ConstantCache(tf, uf, + Rodas4Tableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve, + alg_autodiff(alg)) +end + +function alg_cache(alg::Rodas42, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas42Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, + k5, k6, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +function alg_cache(alg::Rodas42, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rodas4ConstantCache(tf, uf, + Rodas42Tableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve, + alg_autodiff(alg)) +end + +function alg_cache(alg::Rodas4P, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas4PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, + k5, k6, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +function alg_cache(alg::Rodas4P, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rodas4ConstantCache(tf, uf, + Rodas4PTableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve, + alg_autodiff(alg)) +end + +function alg_cache(alg::Rodas4P2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas4P2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, + k5, k6, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +function alg_cache(alg::Rodas4P2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rodas4ConstantCache(tf, uf, + Rodas4P2Tableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve, + alg_autodiff(alg)) +end + +################################################################################ + +### Rosenbrock5 + +struct Rosenbrock5ConstantCache{TF, UF, Tab, JType, WType, F} <: OrdinaryDiffEqConstantCache + tf::TF + uf::UF + tab::Tab + J::JType + W::WType + linsolve::F +end + +@cache mutable struct Rosenbrock5Cache{ + uType, rateType, uNoUnitsType, JType, WType, TabType, + TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: + RosenbrockMutableCache + u::uType + uprev::uType + dense1::rateType + dense2::rateType + dense3::rateType + du::rateType + du1::rateType + du2::rateType + k1::rateType + k2::rateType + k3::rateType + k4::rateType + k5::rateType + k6::rateType + k7::rateType + k8::rateType + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + reltol::RTolType + alg::A + step_limiter!::StepLimiter + stage_limiter!::StageLimiter +end + +TruncatedStacktraces.@truncate_stacktrace Rosenbrock5Cache 1 + +function alg_cache(alg::Rodas5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + dense3 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rosenbrock5Cache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, + k5, k6, k7, k8, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, + linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +function alg_cache(alg::Rodas5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rosenbrock5ConstantCache(tf, uf, + Rodas5Tableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve) +end + +function alg_cache( + alg::Union{Rodas5P, Rodas5Pe, Rodas5Pr}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + dense1 = zero(rate_prototype) + dense2 = zero(rate_prototype) + dense3 = zero(rate_prototype) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + k1 = zero(rate_prototype) + k2 = zero(rate_prototype) + k3 = zero(rate_prototype) + k4 = zero(rate_prototype) + k5 = zero(rate_prototype) + k6 = zero(rate_prototype) + k7 = zero(rate_prototype) + k8 = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + weight = similar(u, uEltypeNoUnits) + recursivefill!(weight, false) + tab = Rodas5PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f, uprev, p) + uf = UJacobianWrapper(f, t, p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) + Pl, Pr = wrapprecs( + alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, + nothing)..., weight, tmp) + linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, + Pl = Pl, Pr = Pr, + assumptions = LinearSolve.OperatorAssumptions(true)) + grad_config = build_grad_config(alg, f, tf, du1, t) + jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) + Rosenbrock5Cache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, + k5, k6, k7, k8, + fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, + linsolve_tmp, + linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, + alg.stage_limiter!) +end + +function alg_cache( + alg::Union{Rodas5P, Rodas5Pe, Rodas5Pr}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tf = TimeDerivativeWrapper(f, u, p) + uf = UDerivativeWrapper(f, t, p) + J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) + linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) + linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) + Rosenbrock5ConstantCache(tf, uf, + Rodas5PTableau(constvalue(uBottomEltypeNoUnits), + constvalue(tTypeNoUnits)), J, W, linsolve) +end + +################################################################################ + +### RosenbrockW6S4O + +@RosenbrockW6S4OS(:cache) diff --git a/src/caches/sdirk_caches.jl b/src/caches/sdirk_caches.jl new file mode 100644 index 0000000000..5664341626 --- /dev/null +++ b/src/caches/sdirk_caches.jl @@ -0,0 +1,998 @@ +abstract type SDIRKMutableCache <: OrdinaryDiffEqMutableCache end + +@cache mutable struct ImplicitEulerCache{ + uType, rateType, uNoUnitsType, N, AV, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + uprev2::uType + fsalfirst::rateType + atmp::uNoUnitsType + nlsolver::N + algebraic_vars::AV + step_limiter!::StepLimiter +end + +function alg_cache(alg::ImplicitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + algebraic_vars = f.mass_matrix === I ? nothing : + [all(iszero, x) for x in eachcol(f.mass_matrix)] + + ImplicitEulerCache( + u, uprev, uprev2, fsalfirst, atmp, nlsolver, algebraic_vars, alg.step_limiter!) +end + +mutable struct ImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + +function alg_cache(alg::ImplicitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + ImplicitEulerConstantCache(nlsolver) +end + +mutable struct ImplicitMidpointConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + +function alg_cache(alg::ImplicitMidpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 2, 1 // 2 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + ImplicitMidpointConstantCache(nlsolver) +end + +@cache mutable struct ImplicitMidpointCache{uType, rateType, N, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + nlsolver::N + step_limiter!::StepLimiter +end + +function alg_cache(alg::ImplicitMidpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 2, 1 // 2 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + ImplicitMidpointCache(u, uprev, fsalfirst, nlsolver, alg.step_limiter!) +end + +mutable struct TrapezoidConstantCache{uType, tType, N} <: OrdinaryDiffEqConstantCache + uprev3::uType + tprev2::tType + nlsolver::N +end + +function alg_cache(alg::Trapezoid, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 2, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + uprev3 = u + tprev2 = t + + TrapezoidConstantCache(uprev3, tprev2, nlsolver) +end + +@cache mutable struct TrapezoidCache{ + uType, rateType, uNoUnitsType, tType, N, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + uprev2::uType + fsalfirst::rateType + atmp::uNoUnitsType + uprev3::uType + tprev2::tType + nlsolver::N + step_limiter!::StepLimiter +end + +function alg_cache(alg::Trapezoid, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 2, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + uprev3 = zero(u) + tprev2 = t + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + TrapezoidCache( + u, uprev, uprev2, fsalfirst, atmp, uprev3, tprev2, nlsolver, alg.step_limiter!) +end + +mutable struct TRBDF2ConstantCache{Tab, N} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::TRBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = TRBDF2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.d, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + TRBDF2ConstantCache(nlsolver, tab) +end + +@cache mutable struct TRBDF2Cache{uType, rateType, uNoUnitsType, Tab, N, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + zprev::uType + zᵧ::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +function alg_cache(alg::TRBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = TRBDF2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.d, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + zprev = zero(u) + zᵧ = zero(u) + + TRBDF2Cache(u, uprev, fsalfirst, zprev, zᵧ, atmp, nlsolver, tab, alg.step_limiter!) +end + +mutable struct SDIRK2ConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + +function alg_cache(alg::SDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + SDIRK2ConstantCache(nlsolver) +end + +@cache mutable struct SDIRK2Cache{uType, rateType, uNoUnitsType, N, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + atmp::uNoUnitsType + nlsolver::N + step_limiter!::StepLimiter +end + +function alg_cache(alg::SDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SDIRK2Cache(u, uprev, fsalfirst, z₁, z₂, atmp, nlsolver, alg.step_limiter!) +end + +struct SDIRK22ConstantCache{uType, tType, N, Tab} <: OrdinaryDiffEqConstantCache + uprev3::uType + tprev2::tType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SDIRK22, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{tTypeNoUnits}, ::Type{uBottomEltypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SDIRK22Tableau(constvalue(uBottomEltypeNoUnits)) + uprev3 = u + tprev2 = t + γ, c = 1, 1 + + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + + SDIRK22ConstantCache(uprev3, tprev2, nlsolver) +end + +@cache mutable struct SDIRK22Cache{ + uType, rateType, uNoUnitsType, tType, N, Tab, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + uprev2::uType + fsalfirst::rateType + atmp::uNoUnitsType + uprev3::uType + tprev2::tType + nlsolver::N + tab::Tab + step_limiter!::StepLimiter +end + +function alg_cache(alg::SDIRK22, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SDIRK22Tableau(constvalue(uBottomEltypeNoUnits)) + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + uprev3 = zero(u) + tprev2 = t + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SDIRK22Cache( + u, uprev, uprev2, fsalfirst, atmp, uprev3, tprev2, nlsolver, tab, alg.step_limiter!) # shouldn't this be SDIRK22Cache instead of SDIRK22? +end + +mutable struct SSPSDIRK2ConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + +function alg_cache(alg::SSPSDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 4, 1 // 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + SSPSDIRK2ConstantCache(nlsolver) +end + +@cache mutable struct SSPSDIRK2Cache{uType, rateType, N} <: SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + nlsolver::N +end + +function alg_cache(alg::SSPSDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1 // 4, 1 // 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SSPSDIRK2Cache(u, uprev, fsalfirst, z₁, z₂, nlsolver) +end + +mutable struct Cash4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::Cash4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Cash4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + Cash4ConstantCache(nlsolver, tab) +end + +@cache mutable struct Cash4Cache{uType, rateType, uNoUnitsType, N, Tab} <: SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::Cash4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = Cash4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + Cash4Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab) +end + +mutable struct SFSDIRK4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + SFSDIRK4ConstantCache(nlsolver, tab) +end + +@cache mutable struct SFSDIRK4Cache{uType, rateType, uNoUnitsType, N, Tab} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK4, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SFSDIRK4Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab) +end + +mutable struct SFSDIRK5ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + SFSDIRK5ConstantCache(nlsolver, tab) +end + +@cache mutable struct SFSDIRK5Cache{uType, rateType, uNoUnitsType, N, Tab} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SFSDIRK5Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, tab) +end + +mutable struct SFSDIRK6ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK6Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + SFSDIRK6ConstantCache(nlsolver, tab) +end + +@cache mutable struct SFSDIRK6Cache{uType, rateType, uNoUnitsType, N, Tab} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK6Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SFSDIRK6Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, tab) +end + +mutable struct SFSDIRK7ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK7, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK7Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + SFSDIRK7ConstantCache(nlsolver, tab) +end + +@cache mutable struct SFSDIRK7Cache{uType, rateType, uNoUnitsType, N, Tab} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK7, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK7Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SFSDIRK7Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, tab) +end + +mutable struct SFSDIRK8ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK8, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK8Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + SFSDIRK8ConstantCache(nlsolver, tab) +end + +@cache mutable struct SFSDIRK8Cache{uType, rateType, uNoUnitsType, N, Tab} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + z₈::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::SFSDIRK8, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = SFSDIRK8Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = zero(u) + z₈ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + SFSDIRK8Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver, tab) +end + +mutable struct Hairer4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache( + alg::Union{Hairer4, Hairer42}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + if alg isa Hairer4 + tab = Hairer4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + else + tab = Hairer42Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + end + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + Hairer4ConstantCache(nlsolver, tab) +end + +@cache mutable struct Hairer4Cache{uType, rateType, uNoUnitsType, Tab, N} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache( + alg::Union{Hairer4, Hairer42}, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + if alg isa Hairer4 + tab = Hairer4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + else # Hairer42 + tab = Hairer42Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + end + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + Hairer4Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab) +end + +@cache mutable struct ESDIRK54I8L2SACache{uType, rateType, uNoUnitsType, Tab, N} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + z₈::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK54I8L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK54I8L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = zero(u) + z₈ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + ESDIRK54I8L2SACache( + u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver, + tab) +end + +mutable struct ESDIRK54I8L2SAConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK54I8L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK54I8L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + ESDIRK54I8L2SAConstantCache(nlsolver, tab) +end + +@cache mutable struct ESDIRK436L2SA2Cache{uType, rateType, uNoUnitsType, Tab, N} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK436L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK436L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + ESDIRK436L2SA2Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, + tab) +end + +mutable struct ESDIRK436L2SA2ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK436L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK436L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + ESDIRK436L2SA2ConstantCache(nlsolver, tab) +end + +@cache mutable struct ESDIRK437L2SACache{uType, rateType, uNoUnitsType, Tab, N} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK437L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK437L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + ESDIRK437L2SACache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, + tab) +end + +mutable struct ESDIRK437L2SAConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK437L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK437L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + ESDIRK437L2SAConstantCache(nlsolver, tab) +end + +@cache mutable struct ESDIRK547L2SA2Cache{uType, rateType, uNoUnitsType, Tab, N} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK547L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK547L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + ESDIRK547L2SA2Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, + tab) +end + +mutable struct ESDIRK547L2SA2ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK547L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK547L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + ESDIRK547L2SA2ConstantCache(nlsolver, tab) +end + +@cache mutable struct ESDIRK659L2SACache{uType, rateType, uNoUnitsType, Tab, N} <: + SDIRKMutableCache + u::uType + uprev::uType + fsalfirst::rateType + z₁::uType + z₂::uType + z₃::uType + z₄::uType + z₅::uType + z₆::uType + z₇::uType + z₈::uType + z₉::uType + atmp::uNoUnitsType + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK659L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, + p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK659L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + z₁ = zero(u) + z₂ = zero(u) + z₃ = zero(u) + z₄ = zero(u) + z₅ = zero(u) + z₆ = zero(u) + z₇ = zero(u) + z₈ = zero(u) + z₉ = nlsolver.z + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + ESDIRK659L2SACache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, z₉, atmp, + nlsolver, tab) +end + +mutable struct ESDIRK659L2SAConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache + nlsolver::N + tab::Tab +end + +function alg_cache(alg::ESDIRK659L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, + uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{false}) where + {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + tab = ESDIRK659L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + γ, c = tab.γ, tab.γ + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) + ESDIRK659L2SAConstantCache(nlsolver, tab) +end diff --git a/src/dense/generic_dense.jl b/src/dense/generic_dense.jl index cf3c461e08..79acf35844 100644 --- a/src/dense/generic_dense.jl +++ b/src/dense/generic_dense.jl @@ -105,13 +105,13 @@ end _ode_addsteps!(integrator.k, integrator.tprev, integrator.uprev, integrator.u, integrator.dt, f, integrator.p, - cache.cache5, + cache.cache4, always_calc_begin, allow_calc_end, force_calc_end) elseif cache_current == 5 _ode_addsteps!(integrator.k, integrator.tprev, integrator.uprev, integrator.u, integrator.dt, f, integrator.p, - cache.cache1, + cache.cache5, always_calc_begin, allow_calc_end, force_calc_end) elseif cache_current == 6 _ode_addsteps!(integrator.k, integrator.tprev, integrator.uprev, diff --git a/src/dense/high_order_rk_addsteps.jl b/src/dense/high_order_rk_addsteps.jl new file mode 100644 index 0000000000..69d14ef78c --- /dev/null +++ b/src/dense/high_order_rk_addsteps.jl @@ -0,0 +1,259 @@ +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP8ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 7 || always_calc_begin + @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache + @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache + @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache + k1 = f(uprev, p, t) + k2 = f(uprev + dt * (a0201 * k1), p, t + c2 * dt) + k3 = f(uprev + dt * (a0301 * k1 + a0302 * k2), p, t + c3 * dt) + k4 = f(uprev + dt * (a0401 * k1 + a0403 * k3), p, t + c4 * dt) + k5 = f(uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4), p, t + c5 * dt) + k6 = f(uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5), p, t + c6 * dt) + k7 = f(uprev + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6), p, + t + c7 * dt) + k8 = f( + uprev + + dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + a0807 * k7), + p, + t + c8 * dt) + k9 = f( + uprev + + dt * + (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + a0907 * k7 + + a0908 * k8), + p, t + c9 * dt) + k10 = f( + uprev + + dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + a1007 * k7 + + a1008 * k8 + a1009 * k9), + p, + t + c10 * dt) + k11 = f( + uprev + + dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + a1107 * k7 + + a1108 * k8 + a1109 * k9 + a1110 * k10), + p, + t + c11 * dt) + k12 = f( + uprev + + dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + a1207 * k7 + + a1208 * k8 + a1209 * k9 + a1210 * k10 + a1211 * k11), + p, + t + dt) + kupdate = b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + b10 * k10 + b11 * k11 + + b12 * k12 + utmp = uprev + dt * kupdate + k13 = f(utmp, p, t + dt) + k14 = f( + uprev + + dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + a1409 * k9 + a1410 * k10 + + a1411 * k11 + a1412 * k12 + a1413 * k13), + p, + t + c14 * dt) + k15 = f( + uprev + + dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + a1508 * k8 + a1511 * k11 + + a1512 * k12 + a1513 * k13 + a1514 * k14), + p, + t + c15 * dt) + k16 = f( + uprev + + dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + a1608 * k8 + a1609 * k9 + + a1613 * k13 + a1614 * k14 + a1615 * k15), + p, + t + c16 * dt) + udiff = kupdate + copyat_or_push!(k, 1, udiff) + bspl = k1 - udiff + copyat_or_push!(k, 2, bspl) + copyat_or_push!(k, 3, udiff - k13 - bspl) + copyat_or_push!(k, 4, + (d401 * k1 + d406 * k6 + d407 * k7 + d408 * k8 + d409 * k9 + + d410 * k10 + d411 * k11 + d412 * k12 + d413 * k13 + d414 * k14 + + d415 * k15 + d416 * k16)) + copyat_or_push!(k, 5, + (d501 * k1 + d506 * k6 + d507 * k7 + d508 * k8 + d509 * k9 + + d510 * k10 + d511 * k11 + d512 * k12 + d513 * k13 + d514 * k14 + + d515 * k15 + d516 * k16)) + copyat_or_push!(k, 6, + (d601 * k1 + d606 * k6 + d607 * k7 + d608 * k8 + d609 * k9 + + d610 * k10 + d611 * k11 + d612 * k12 + d613 * k13 + d614 * k14 + + d615 * k15 + d616 * k16)) + copyat_or_push!(k, 7, + (d701 * k1 + d706 * k6 + d707 * k7 + d708 * k8 + d709 * k9 + + d710 * k10 + d711 * k11 + d712 * k12 + d713 * k13 + d714 * k14 + + d715 * k15 + d716 * k16)) + end +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP8Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 7 || always_calc_begin + @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache.tab + @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache.tab + @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache.tab + @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, udiff, bspl, dense_tmp3, dense_tmp4, dense_tmp5, dense_tmp6, dense_tmp7, kupdate, utilde, tmp = cache + utmp = utilde + f(k1, uprev, p, t) + @.. broadcast=false tmp=uprev + dt * (a0201 * k1) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false tmp=uprev + dt * (a0301 * k1 + a0302 * k2) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false tmp=uprev + dt * (a0401 * k1 + a0403 * k3) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false tmp=uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false tmp=uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false tmp=uprev + + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false tmp=uprev + + dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + + a0807 * k7) + f(k8, tmp, p, t + c8 * dt) + @.. broadcast=false tmp=uprev + + dt * (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + + a0907 * k7 + a0908 * k8) + f(k9, tmp, p, t + c9 * dt) + @.. broadcast=false tmp=uprev + + dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + + a1007 * k7 + a1008 * k8 + a1009 * k9) + f(k10, tmp, p, t + c10 * dt) + @.. broadcast=false tmp=uprev + + dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + + a1107 * k7 + a1108 * k8 + a1109 * k9 + a1110 * k10) + f(k11, tmp, p, t + c11 * dt) + @.. broadcast=false tmp=uprev + + dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + + a1207 * k7 + a1208 * k8 + a1209 * k9 + a1210 * k10 + + a1211 * k11) + f(k12, tmp, p, t + dt) + @.. broadcast=false kupdate=b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + + b10 * k10 + b11 * k11 + b12 * k12 + @.. broadcast=false utmp=uprev + dt * kupdate + f(k13, utmp, p, t + dt) + @.. broadcast=false tmp=uprev + + dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + a1409 * k9 + + a1410 * k10 + a1411 * k11 + a1412 * k12 + a1413 * k13) + f(k14, tmp, p, t + c14 * dt) + @.. broadcast=false tmp=uprev + + dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + a1508 * k8 + + a1511 * k11 + a1512 * k12 + a1513 * k13 + a1514 * k14) + f(k15, tmp, p, t + c15 * dt) + @.. broadcast=false tmp=uprev + + dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + a1608 * k8 + + a1609 * k9 + a1613 * k13 + a1614 * k14 + a1615 * k15) + f(k16, tmp, p, t + c16 * dt) + copyto!(udiff, kupdate) + copyat_or_push!(k, 1, udiff) + @.. broadcast=false tmp=k1 - udiff + copyat_or_push!(k, 2, tmp) + @.. broadcast=false tmp=udiff - k13 - bspl + copyat_or_push!(k, 3, tmp) + @.. broadcast=false tmp=(d401 * k1 + d406 * k6 + d407 * k7 + d408 * k8 + d409 * k9 + + d410 * k10 + d411 * k11 + d412 * k12 + d413 * k13 + + d414 * k14 + d415 * k15 + d416 * k16) + copyat_or_push!(k, 4, tmp) + @.. broadcast=false tmp=(d501 * k1 + d506 * k6 + d507 * k7 + d508 * k8 + d509 * k9 + + d510 * k10 + d511 * k11 + d512 * k12 + d513 * k13 + + d514 * k14 + d515 * k15 + d516 * k16) + copyat_or_push!(k, 5, tmp) + @.. broadcast=false tmp=(d601 * k1 + d606 * k6 + d607 * k7 + d608 * k8 + d609 * k9 + + d610 * k10 + d611 * k11 + d612 * k12 + d613 * k13 + + d614 * k14 + d615 * k15 + d616 * k16) + copyat_or_push!(k, 6, tmp) + @.. broadcast=false tmp=(d701 * k1 + d706 * k6 + d707 * k7 + d708 * k8 + d709 * k9 + + d710 * k10 + d711 * k11 + d712 * k12 + d713 * k13 + + d714 * k14 + d715 * k15 + d716 * k16) + copyat_or_push!(k, 7, tmp) + end +end + +#= +@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::DP8Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) + if length(k)<7 || always_calc_begin + @unpack c7,c8,c9,c10,c11,c6,c5,c4,c3,c2,b1,b6,b7,b8,b9,b10,b11,b12,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211 = cache.tab + @unpack c14,c15,c16,a1401,a1407,a1408,a1409,a1410,a1411,a1412,a1413,a1501,a1506,a1507,a1508,a1511,a1512,a1513,a1514,a1601,a1606,a1607,a1608,a1609,a1613,a1614,a1615 = cache.tab + @unpack d401,d406,d407,d408,d409,d410,d411,d412,d413,d414,d415,d416,d501,d506,d507,d508,d509,d510,d511,d512,d513,d514,d515,d516,d601,d606,d607,d608,d609,d610,d611,d612,d613,d614,d615,d616,d701,d706,d707,d708,d709,d710,d711,d712,d713,d714,d715,d716 = cache.tab + @unpack k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15,k16,udiff,bspl,dense_tmp3,dense_tmp4,dense_tmp5,dense_tmp6,dense_tmp7,kupdate,utilde,tmp = cache + utmp = utilde + k = [cache.udiff,cache.bspl,cache.dense_tmp3,cache.dense_tmp4,cache.dense_tmp5,cache.dense_tmp6,cache.dense_tmp7] + uidx = eachindex(u) + f(k1,uprev,p,t) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0201*k1[i]) + end + f(k2,tmp,p,t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0301*k1[i]+a0302*k2[i]) + end + f(k3,tmp,p,t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0401*k1[i]+a0403*k3[i]) + end + f(k4,tmp,p,t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0501*k1[i]+a0503*k3[i]+a0504*k4[i]) + end + f(k5,tmp,p,t+c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0601*k1[i]+a0604*k4[i]+a0605*k5[i]) + end + f(k6,tmp,p,t+c6*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0701*k1[i]+a0704*k4[i]+a0705*k5[i]+a0706*k6[i]) + end + f(k7,tmp,p,t+c7*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0801*k1[i]+a0804*k4[i]+a0805*k5[i]+a0806*k6[i]+a0807*k7[i]) + end + f(k8,tmp,p,t+c8*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0901*k1[i]+a0904*k4[i]+a0905*k5[i]+a0906*k6[i]+a0907*k7[i]+a0908*k8[i]) + end + f(k9,tmp,p,t+c9*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1001*k1[i]+a1004*k4[i]+a1005*k5[i]+a1006*k6[i]+a1007*k7[i]+a1008*k8[i]+a1009*k9[i]) + end + f(k10,tmp,p,t+c10*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1101*k1[i]+a1104*k4[i]+a1105*k5[i]+a1106*k6[i]+a1107*k7[i]+a1108*k8[i]+a1109*k9[i]+a1110*k10[i]) + end + f(k11,tmp,p,t+c11*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1201*k1[i]+a1204*k4[i]+a1205*k5[i]+a1206*k6[i]+a1207*k7[i]+a1208*k8[i]+a1209*k9[i]+a1210*k10[i]+a1211*k11[i]) + end + f(k12,tmp,p,t+dt) + @tight_loop_macros for i in uidx + @inbounds kupdate[i] = b1*k1[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]+b10*k10[i]+b11*k11[i]+b12*k12[i] + @inbounds utmp[i] = uprev[i] + dt*kupdate[i] + end + f(k13,utmp,p,t+dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1401*k1[i]+a1407*k7[i]+a1408*k8[i]+a1409*k9[i]+a1410*k10[i]+a1411*k11[i]+a1412*k12[i]+a1413*k13[i]) + end + f(k14,tmp,p,t+c14*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1501*k1[i]+a1506*k6[i]+a1507*k7[i]+a1508*k8[i]+a1511*k11[i]+a1512*k12[i]+a1513*k13[i]+a1514*k14[i]) + end + f(k15,tmp,p,t+c15*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1601*k1[i]+a1606*k6[i]+a1607*k7[i]+a1608*k8[i]+a1609*k9[i]+a1613*k13[i]+a1614*k14[i]+a1615*k15[i]) + end + f(k16,tmp,p,t+c16*dt) + @tight_loop_macros for i in uidx + @inbounds udiff[i]= kupdate[i] + @inbounds bspl[i] = k1[i] - udiff[i] + @inbounds k[3][i] = udiff[i] - k13[i] - bspl[i] + @inbounds k[4][i] = (d401*k1[i]+d406*k6[i]+d407*k7[i]+d408*k8[i]+d409*k9[i]+d410*k10[i]+d411*k11[i]+d412*k12[i]+d413*k13[i]+d414*k14[i]+d415*k15[i]+d416*k16[i]) + @inbounds k[5][i] = (d501*k1[i]+d506*k6[i]+d507*k7[i]+d508*k8[i]+d509*k9[i]+d510*k10[i]+d511*k11[i]+d512*k12[i]+d513*k13[i]+d514*k14[i]+d515*k15[i]+d516*k16[i]) + @inbounds k[6][i] = (d601*k1[i]+d606*k6[i]+d607*k7[i]+d608*k8[i]+d609*k9[i]+d610*k10[i]+d611*k11[i]+d612*k12[i]+d613*k13[i]+d614*k14[i]+d615*k15[i]+d616*k16[i]) + @inbounds k[7][i] = (d701*k1[i]+d706*k6[i]+d707*k7[i]+d708*k8[i]+d709*k9[i]+d710*k10[i]+d711*k11[i]+d712*k12[i]+d713*k13[i]+d714*k14[i]+d715*k15[i]+d716*k16[i]) + end + end +end +=# diff --git a/src/dense/interpolants.jl b/src/dense/interpolants.jl new file mode 100644 index 0000000000..ebf6d226bc --- /dev/null +++ b/src/dense/interpolants.jl @@ -0,0 +1,1699 @@ +RK_WITH_SPECIAL_INTERPOLATIONS = Union{FunctionMapConstantCache, FunctionMapCache, + DP5ConstantCache, DP5Cache, + Tsit5ConstantCache, Tsit5Cache, + OwrenZen3ConstantCache, OwrenZen3Cache, + OwrenZen4ConstantCache, OwrenZen4Cache, + OwrenZen5ConstantCache, OwrenZen5Cache, + BS5ConstantCache, BS5Cache +} +function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::RK_WITH_SPECIAL_INTERPOLATIONS, + idxs, T::Type{Val{D}}, differential_vars) where {D} + throw(DerivativeOrderNotPossibleError()) +end + +function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::RK_WITH_SPECIAL_INTERPOLATIONS, + idxs, T::Type{Val{D}}, differential_vars) where {D} + throw(DerivativeOrderNotPossibleError()) +end + +#### + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + y₀ +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + y₀[idxs] +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + recursivecopy!(out, y₀) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{FunctionMapConstantCache, FunctionMapCache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @views out[idxs] .= y₀[idxs] +end + +""" +Hairer Norsett Wanner Solving Ordinary Differential Euations I - Nonstiff Problems Page 192 +""" +@def dp5pre0 begin + b10 = Θ + b20 = Θ * (1 - Θ) + b30 = Θ * b20 + b40 = b20^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5ConstantCache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @inbounds y₀ + dt * (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5Cache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @inbounds @.. broadcast=false y₀+dt * + (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b10 + k[2][idxs] * b20 + + k[3][idxs] * b30 + k[4][idxs] * b40) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @inbounds @.. broadcast=false out=y₀ + + dt * + (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @dp5pre0 + @views @.. broadcast=false out=y₀[idxs] + + dt * + (k[1][idxs] * b10 + k[2][idxs] * b20 + k[3][idxs] * b30 + + k[4][idxs] * b40) + out +end + +@def dp5pre1 begin + b20diff = @evalpoly(Θ, 1, -2) + b30diff = Θ * @evalpoly(Θ, 2, -3) + b40diff = Θ * @evalpoly(Θ, 2, -6, 4) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @inbounds @.. broadcast=false k[1]+k[2]*b20diff+k[3]*b30diff+k[4]*b40diff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @views @.. broadcast=false k[1][idxs]+k[2][idxs]*b20diff+k[3][idxs]*b30diff+ + k[4][idxs]*b40diff +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @inbounds @.. broadcast=false out=k[1] + k[2] * b20diff + k[3] * b30diff + + k[4] * b40diff + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @dp5pre1 + @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] * b20diff + + k[3][idxs] * b30diff + k[4][idxs] * b40diff + out +end + +@def dp5pre2 begin + b20diff2 = -2 + b30diff2 = @evalpoly(Θ, 2, -6) + b40diff2 = @evalpoly(Θ, 2, -12, 12) + invdt = inv(dt) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @inbounds @.. broadcast=false (k[2] * b20diff2 + k[3] * b30diff2 + + k[4] * b40diff2)*invdt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @views @.. broadcast=false (k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + + k[4][idxs] * b40diff2)*invdt +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @inbounds @.. broadcast=false out=(k[2] * b20diff2 + k[3] * b30diff2 + + k[4] * b40diff2) * + invdt + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @dp5pre2 + @views @.. broadcast=false out=(k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + + k[4][idxs] * b40diff2) * invdt + out +end + +@def dp5pre3 begin + b30diff3 = -6 + b40diff3 = @evalpoly(Θ, -12, 24) + invdt2 = inv(dt)^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @inbounds @.. broadcast=false (k[3] * b30diff3 + k[4] * b40diff3)*invdt2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @views @.. broadcast=false (k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3)*invdt2 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @inbounds @.. broadcast=false out=(k[3] * b30diff3 + k[4] * b40diff3) * invdt2 + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @dp5pre3 + @views @.. broadcast=false out=(k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3) * invdt2 + out +end + +@def dp5pre4 begin + b40diff4invdt3 = 24 * inv(dt)^3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @inbounds @.. broadcast=false k[4]*b40diff4invdt3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @views @.. broadcast=false k[4][idxs]*b40diff4invdt3 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @inbounds @.. broadcast=false out=k[4] * b40diff4invdt3 + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP5ConstantCache, DP5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @dp5pre4 + @views @.. broadcast=false out=k[4][idxs] * b40diff4invdt3 + out +end + +""" +Runge–Kutta pairs of order 5(4) satisfying only the first column +simplifying assumption + +Ch. Tsitouras +""" +@def tsit5unpack begin + var"#T#" = constvalue(recursive_unitless_bottom_eltype(y₁)) + r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, r62, r63, r64, r72, r73, r74 = Tsit5Interp(var"#T#") +end + +@def tsit5pre0 begin + @tsit5unpack + Θ² = Θ * Θ + b1Θ = Θ * @evalpoly(Θ, r11, r12, r13, r14) + b2Θ = Θ² * @evalpoly(Θ, r22, r23, r24) + b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) + b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) + b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) + b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) + b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + #@.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[2]*b2Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ) + return @inbounds y₀ + + dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + + k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + return @inbounds @.. broadcast=false y₀+dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + + k[4] * b4Θ + + k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + return y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @inbounds @.. broadcast=false out=y₀ + + dt * + (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + + k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) + out +end + +@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @inbounds @simd ivdep for i in eachindex(out) + out[i] = y₀[i] + + dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + + k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) + end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @views @.. broadcast=false out=y₀[idxs] + + dt * + (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + + k[7][idxs] * b7Θ) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[2][i]*b2Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ) + #end + out +end + +@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @tsit5pre0 + @inbounds for (j, i) in enumerate(idxs) + out[j] = y₀[i] + + dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + + k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) + end + out +end + +@def tsit5pre1 begin + @tsit5unpack + b1Θdiff = @evalpoly(Θ, r11, 2*r12, 3*r13, 4*r14) + b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23, 4*r24) + b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34) + b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44) + b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54) + b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64) + b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + # return @.. broadcast=false k[1]*b1Θdiff + k[2]*b2Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff + return @inbounds k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + return @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+ + k[4]*b4Θdiff+k[5]*b5Θdiff+k[6]*b6Θdiff+k[7]*b7Θdiff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + # return @.. broadcast=false k[1][idxs]*b1Θdiff + k[2][idxs]*b2Θdiff + k[3][idxs]*b3Θdiff + k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + k[7][idxs]*b7Θdiff + return k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + + k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + + k[7] * b7Θdiff + #@inbounds for i in eachindex(out) + # out[i] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @tsit5pre1 + @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + #end + out +end + +@def tsit5pre2 begin + @tsit5unpack + b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14) + b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23, 12*r24) + b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34) + b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44) + b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54) + b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64) + b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74) + invdt = inv(dt) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + # return @.. broadcast=false k[1]*b1Θdiff2 + k[2]*b2Θdiff2 + k[3]*b3Θdiff2 + k[4]*b4Θdiff2 + k[5]*b5Θdiff2 + k[6]*b6Θdiff2 + k[7]*b7Θdiff2 + return @inbounds (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2) * invdt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + # return @.. broadcast=false k[1][idxs]*b1Θdiff2 + k[2][idxs]*b2Θdiff2 + k[3][idxs]*b3Θdiff2 + k[4][idxs]*b4Θdiff2 + k[5][idxs]*b5Θdiff2 + k[6][idxs]*b6Θdiff2 + k[7][idxs]*b7Θdiff2 + return (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + + k[7][idxs] * b7Θdiff2) * invdt +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2 + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + + k[7] * b7Θdiff2) * invdt + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{2}}, differential_vars::Nothing) + @tsit5pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + + k[7][idxs] * b7Θdiff2) * invdt + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt + #end + out +end + +@def tsit5pre3 begin + @tsit5unpack + b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14) + b2Θdiff3 = @evalpoly(Θ, 6*r23, 24*r24) + b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34) + b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44) + b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54) + b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64) + b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74) + invdt2 = inv(dt)^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + # return @.. broadcast=false k[1]*b1Θdiff3 + k[2]*b2Θdiff3 + k[3]*b3Θdiff3 + k[4]*b4Θdiff3 + k[5]*b5Θdiff3 + k[6]*b6Θdiff3 + k[7]*b7Θdiff3 + return @inbounds (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3) * invdt2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + # return @.. broadcast=false k[1][idxs]*b1Θdiff3 + k[2][idxs]*b2Θdiff3 + k[3][idxs]*b3Θdiff3 + k[4][idxs]*b4Θdiff3 + k[5][idxs]*b5Θdiff3 + k[6][idxs]*b6Θdiff3 + k[7][idxs]*b7Θdiff3 + return (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + + k[7][idxs] * b7Θdiff3) * invdt2 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3 + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + + k[7] * b7Θdiff3) * invdt2 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{3}}, differential_vars::Nothing) + @tsit5pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + + k[7][idxs] * b7Θdiff3) * invdt2 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 + #end + out +end + +@def tsit5pre4 begin + @tsit5unpack + b1Θdiff4 = 24 * r14 + b2Θdiff4 = 24 * r24 + b3Θdiff4 = 24 * r34 + b4Θdiff4 = 24 * r44 + b5Θdiff4 = 24 * r54 + b6Θdiff4 = 24 * r64 + b7Θdiff4 = 24 * r74 + invdt3 = inv(dt)^3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + # return @.. broadcast=false k[1]*b1Θdiff4 + k[2]*b2Θdiff4 + k[3]*b3Θdiff4 + k[4]*b4Θdiff4 + k[5]*b5Θdiff4 + k[6]*b6Θdiff4 + k[7]*b7Θdiff4 + return @inbounds (k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4) * invdt3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + # return @.. broadcast=false k[1][idxs]*b1Θdiff4 + k[2][idxs]*b2Θdiff4 + k[3][idxs]*b3Θdiff4 + k[4][idxs]*b4Θdiff4 + k[5][idxs]*b5Θdiff4 + k[6][idxs]*b6Θdiff4 + k[7][idxs]*b7Θdiff4 + return (k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + + k[7][idxs] * b7Θdiff4) * invdt3 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + + k[4] * b4Θdiff4 + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + + k[7] * b7Θdiff4) * invdt3 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, + T::Type{Val{4}}, differential_vars::Nothing) + @tsit5pre4 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + + k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + + k[7][idxs] * b7Θdiff4) * invdt3 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 + #end + out +end + +""" +""" +@def owrenzen3unpack begin + if cache isa OrdinaryDiffEqMutableCache + @unpack r13, r12, r23, r22, r33, r32 = cache.tab + else + @unpack r13, r12, r23, r22, r33, r32 = cache + end +end + +@def owrenzen3pre0 begin + @owrenzen3unpack + Θ² = Θ * Θ + b1Θ = Θ * @evalpoly(Θ, 1, r12, r13) + b2Θ = Θ² * @evalpoly(Θ, r22, r23) + b3Θ = Θ² * @evalpoly(Θ, r32, r33) + b4Θ = Θ² * @evalpoly(Θ, -1, 1) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 + @inbounds @.. broadcast=false y₀+dt * + (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 + @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 + @inbounds @.. broadcast=false out=y₀ + + dt * + (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen3pre0 + @views @.. broadcast=false out=y₀[idxs] + + dt * + (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ) + out +end + +@def owrenzen3pre1 begin + @owrenzen3unpack + b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13) + b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23) + b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33) + b4Θdiff = Θ * @evalpoly(Θ, -2, 3) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen3pre1 + @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen3pre1 + @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[2][idxs]*b2Θdiff+k[3][idxs]*b3Θdiff+ + k[4][idxs]*b4Θdiff +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen3pre1 + @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + + k[4] * b4Θdiff + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen3pre1 + @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + out +end + +@def owrenzen3pre2 begin + @owrenzen3unpack + b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13) + b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23) + b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33) + b4Θdiff2 = @evalpoly(Θ, -2, 6) + invdt = inv(dt) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @inbounds @.. broadcast=false (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2)*invdt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2)*invdt +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + + k[4] * b4Θdiff2) * invdt + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen3pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2) * invdt + out +end + +@def owrenzen3pre3 begin + @owrenzen3unpack + b1Θdiff3 = 6 * r13 + b2Θdiff3 = 6 * r23 + b3Θdiff3 = 6 * r33 + b4Θdiff3 = 6 + invdt2 = inv(dt)^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3)*invdt2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3)*invdt2 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + + k[4] * b4Θdiff3) * invdt2 + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen3pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3) * invdt2 + out +end + +""" +""" +@def owrenzen4unpack begin + if cache isa OrdinaryDiffEqMutableCache + @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache.tab + else + @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache + end +end + +@def owrenzen4pre0 begin + @owrenzen4unpack + Θ² = Θ * Θ + b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14) + b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) + b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) + b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) + b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen4pre0 + # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ) + return @inbounds y₀ + + dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen4pre0 + # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + + # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ) + return y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen4pre0 + @inbounds @.. broadcast=false out=y₀ + + dt * + (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ) + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen4pre0 + @inbounds @.. broadcast=false out=y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + + k[6][idxs] * b6Θ) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ) + #end + out +end + +@def owrenzen4pre1 begin + @owrenzen4unpack + b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14) + b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34) + b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44) + b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54) + b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen4pre1 + @inbounds @.. broadcast=false k[1]*b1Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff+k[5]*b5Θdiff+ + k[6]*b6Θdiff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen4pre1 + @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[3][idxs]*b3Θdiff+k[4][idxs]*b4Θdiff+ + k[5][idxs]*b5Θdiff+k[6][idxs]*b6Θdiff +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen4pre1 + @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + k[6] * b6Θdiff + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen4pre1 + @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + out +end + +@def owrenzen4pre2 begin + @owrenzen4unpack + b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14) + b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34) + b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44) + b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54) + b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64) + invdt = inv(dt) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen4pre2 + @.. broadcast=false (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2)*invdt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen4pre2 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2)*invdt +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen4pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2) * invdt + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen4pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2) * invdt + out +end + +@def owrenzen4pre3 begin + @owrenzen4unpack + b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14) + b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34) + b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44) + b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54) + b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64) + invdt2 = inv(dt)^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen4pre3 + @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3)*invdt2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen4pre3 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3)*invdt2 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen4pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3) * invdt2 + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen4pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3) * invdt2 + out +end + +@def owrenzen4pre4 begin + @owrenzen4unpack + b1Θdiff4 = 24 * r14 + b3Θdiff4 = 24 * r34 + b4Θdiff4 = 24 * r44 + b5Θdiff4 = 24 * r54 + b6Θdiff4 = 24 * r64 + invdt3 = inv(dt)^3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen4pre4 + @.. broadcast=false (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4)*invdt3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen4pre4 + @views @.. broadcast=false (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4)*invdt3 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen4pre4 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4) * invdt3 + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen4pre4 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4) * invdt3 + out +end + +""" +""" +@def owrenzen5unpack begin + if cache isa OrdinaryDiffEqMutableCache + @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache.tab + else + @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache + end +end + +@def owrenzen5pre0 begin + @owrenzen5unpack + Θ² = Θ * Θ + b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14, r15) + b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34, r35) + b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44, r45) + b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54, r55) + b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64, r65) + b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74, r75) + b8Θ = Θ² * @evalpoly(Θ, r82, r83, r84, r85) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen5pre0 + # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + + # k[7]*b7Θ + k[8]*b8Θ) + return @inbounds y₀ + + dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ + + k[7] * b7Θ + k[8] * b8Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen5pre0 + # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + + # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + + # k[7][idxs]*b7Θ + k[8][idxs]*b8Θ) + return y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + + k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen5pre0 + @inbounds @.. broadcast=false out=y₀ + + dt * + (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ + + k[7] * b7Θ + k[8] * b8Θ) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{0}}, differential_vars::Nothing) + @owrenzen5pre0 + @views @.. broadcast=false out=y₀[idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + + k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + + # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) + #end + out +end + +@def owrenzen5pre1 begin + @owrenzen5unpack + b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14, 5*r15) + b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34, 5*r35) + b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44, 5*r45) + b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54, 5*r55) + b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64, 5*r65) + b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74, 5*r75) + b8Θdiff = Θ * @evalpoly(Θ, 2*r82, 3*r83, 4*r84, 5*r85) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen5pre1 + return @inbounds k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + k[5] * b5Θdiff + + k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen5pre1 + k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + + k[6][idxs] * b6Θdiff + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen5pre1 + @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff + + k[8] * b8Θdiff + #@inbounds for i in eachindex(out) + # out[i] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + + # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{1}}, differential_vars::Nothing) + @owrenzen5pre1 + @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + + # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + #end + out +end + +@def owrenzen5pre2 begin + @owrenzen5unpack + b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14, 20*r15) + b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34, 20*r35) + b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44, 20*r45) + b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54, 20*r55) + b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64, 20*r65) + b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74, 20*r75) + b8Θdiff2 = @evalpoly(Θ, 2*r82, 6*r83, 12*r84, 20*r85) + invdt = inv(dt) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen5pre2 + return @inbounds (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + + k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + k[8] * b8Θdiff2) * invdt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen5pre2 + (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + + k[6][idxs] * b6Θdiff2 + k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen5pre2 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + + k[8] * b8Θdiff2) * invdt + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + + # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{2}}, differential_vars::Nothing) + @owrenzen5pre2 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + + k[4][idxs] * b4Θdiff2 + + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + + k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + + # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt + #end + out +end + +@def owrenzen5pre3 begin + @owrenzen5unpack + b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14, 60*r15) + b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34, 60*r35) + b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44, 60*r45) + b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54, 60*r55) + b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64, 60*r65) + b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74, 60*r75) + b8Θdiff3 = @evalpoly(Θ, 6*r83, 24*r84, 60*r85) + invdt2 = inv(dt)^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen5pre3 + return @inbounds (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + + k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + k[8] * b8Θdiff3) * invdt2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen5pre3 + (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + + k[6][idxs] * b6Θdiff3 + k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen5pre3 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + + k[8] * b8Θdiff3) * invdt2 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + + # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{3}}, differential_vars::Nothing) + @owrenzen5pre3 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + + k[4][idxs] * b4Θdiff3 + + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + + k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + + # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 + #end + out +end + +@def owrenzen5pre4 begin + @owrenzen5unpack + b1Θdiff4 = @evalpoly(Θ, 24*r14, 120*r15) + b3Θdiff4 = @evalpoly(Θ, 24*r34, 120*r35) + b4Θdiff4 = @evalpoly(Θ, 24*r44, 120*r45) + b5Θdiff4 = @evalpoly(Θ, 24*r54, 120*r55) + b6Θdiff4 = @evalpoly(Θ, 24*r64, 120*r65) + b7Θdiff4 = @evalpoly(Θ, 24*r74, 120*r75) + b8Θdiff4 = @evalpoly(Θ, 24*r84, 120*r85) + invdt3 = inv(dt)^3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + return @inbounds (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + + k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + k[8] * b8Θdiff4) * invdt3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + + k[6][idxs] * b6Θdiff4 + k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + + k[8] * b8Θdiff4) * invdt3 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + + # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{4}}, differential_vars::Nothing) + @owrenzen5pre4 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + + k[4][idxs] * b4Θdiff4 + + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + + k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + + # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 + #end + out +end + +@def owrenzen5pre5 begin + @owrenzen5unpack + b1Θdiff5 = 120 * r15 + b3Θdiff5 = 120 * r35 + b4Θdiff5 = 120 * r45 + b5Θdiff5 = 120 * r55 + b6Θdiff5 = 120 * r65 + b7Θdiff5 = 120 * r75 + b8Θdiff5 = 120 * r85 + invdt4 = inv(dt)^4 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + return @inbounds (k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + + k[5] * b5Θdiff5 + + k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + k[8] * b8Θdiff5) * invdt4 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + (k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + k[4][idxs] * b4Θdiff5 + + k[5][idxs] * b5Θdiff5 + + k[6][idxs] * b6Θdiff5 + k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + @inbounds @.. broadcast=false out=(k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + + k[5] * b5Θdiff5 + k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + + k[8] * b8Θdiff5) * invdt4 + #@inbounds for i in eachindex(out) + # out[i] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + + # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, + idxs, T::Type{Val{5}}, differential_vars::Nothing) + @owrenzen5pre5 + @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + + k[4][idxs] * b4Θdiff5 + + k[5][idxs] * b5Θdiff5 + k[6][idxs] * b6Θdiff5 + + k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + + # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 + #end + out +end + +""" +Coefficients taken from RKSuite +""" +@def bs5unpack begin + if cache isa OrdinaryDiffEqMutableCache + @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache.tab + else + @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache + end +end + +@def bs5pre0 begin + @bs5unpack + Θ² = Θ * Θ + b1Θ = Θ² * @evalpoly(Θ, r012, r013, r014, r015, r016) + b3Θ = Θ² * @evalpoly(Θ, r032, r033, r034, r035, r036) + b4Θ = Θ² * @evalpoly(Θ, r042, r043, r044, r045, r046) + b5Θ = Θ² * @evalpoly(Θ, r052, r053, r054, r055, r056) + b6Θ = Θ² * @evalpoly(Θ, r062, r063, r064, r065, r066) + b7Θ = Θ² * @evalpoly(Θ, r072, r073, r074, r075, r076) + b8Θ = Θ² * @evalpoly(Θ, r082, r083, r084, r085, r086) + b9Θ = (Θ² * Θ) * @evalpoly(Θ, r093, r094, r095, + r096) + b10Θ = Θ² * @evalpoly(Θ, r102, r103, r104, r105, r106) + b11Θ = Θ² * @evalpoly(Θ, r112, r113, r114, r115, r116) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5ConstantCache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) + return @inbounds y₀ + dt * Θ * k[1] + + dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + k[10] * b10Θ + + k[11] * b11Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5Cache, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) + return @inbounds @.. broadcast=false y₀+dt*Θ*k[1]+ + dt*(k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + + k[5] * b5Θ + + k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + + k[9] * b9Θ + k[10] * b10Θ + k[11] * b11Θ) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + # return @.. broadcast=false y₀[idxs] + dt*Θ*k[1][idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + + # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + k[7][idxs]*b7Θ + + # k[8][idxs]*b8Θ + k[9][idxs]*b9Θ + k[10][idxs]*b10Θ + k[11][idxs]*b11Θ) + return y₀[idxs] + dt * Θ * k[1][idxs] + + dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + + k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + + k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + @inbounds @.. broadcast=false out=y₀ + dt * Θ * k[1] + + dt * + (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + + k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + + k[10] * b10Θ + k[11] * b11Θ) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + @bs5pre0 + @views @.. broadcast=false out=y₀[idxs] + dt * Θ * k[1][idxs] + + dt * + (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + k[4][idxs] * b4Θ + + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + + k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + + k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) + #end + out +end + +@def bs5pre1 begin + @bs5unpack + Θ² = Θ * Θ + b1Θdiff = Θ * @evalpoly(Θ, 2*r012, 3*r013, 4*r014, 5*r015, 6*r016) + b3Θdiff = Θ * @evalpoly(Θ, 2*r032, 3*r033, 4*r034, 5*r035, 6*r036) + b4Θdiff = Θ * @evalpoly(Θ, 2*r042, 3*r043, 4*r044, 5*r045, 6*r046) + b5Θdiff = Θ * @evalpoly(Θ, 2*r052, 3*r053, 4*r054, 5*r055, 6*r056) + b6Θdiff = Θ * @evalpoly(Θ, 2*r062, 3*r063, 4*r064, 5*r065, 6*r066) + b7Θdiff = Θ * @evalpoly(Θ, 2*r072, 3*r073, 4*r074, 5*r075, 6*r076) + b8Θdiff = Θ * @evalpoly(Θ, 2*r082, 3*r083, 4*r084, 5*r085, 6*r086) + b9Θdiff = Θ² * @evalpoly(Θ, 3*r093, 4*r094, 5*r095, 6*r096) + b10Θdiff = Θ * @evalpoly(Θ, 2*r102, 3*r103, 4*r104, 5*r105, 6*r106) + b11Θdiff = Θ * @evalpoly(Θ, 2*r112, 3*r113, 4*r114, 5*r115, 6*r116) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + # return @.. broadcast=false k[1] + k[1]*b1Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff + k[8]*b8Θdiff + k[9]*b9Θdiff + k[10]*b10Θdiff + k[11]*b11Θdiff + return @inbounds k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + + k[5] * b5Θdiff + + k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + + k[10] * b10Θdiff + k[11] * b11Θdiff +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + # return @.. broadcast=false k[1][idxs] + k[1][idxs]*b1Θdiff + k[3][idxs]*b3Θdiff + + # k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + + # k[7][idxs]*b7Θdiff + k[8][idxs]*b8Θdiff + k[9][idxs]*b9Θdiff + + # k[10][idxs]*b10Θdiff + k[11][idxs]*b11Θdiff + return @inbounds k[1][idxs] + k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + + k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + k[9][idxs] * b9Θdiff + + k[10][idxs] * b10Θdiff + k[11][idxs] * b11Θdiff +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + @inbounds @.. broadcast=false out=k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + + k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + + k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + + k[10] * b10Θdiff + k[11] * b11Θdiff + #@inbounds for i in eachindex(out) + # out[i] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{BS5ConstantCache, BS5Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + @bs5pre1 + @views @.. broadcast=false out=k[1][idxs] + k[1][idxs] * b1Θdiff + + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + + k[9][idxs] * b9Θdiff + k[10][idxs] * b10Θdiff + + k[11][idxs] * b11Θdiff + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff + #end + out +end + +""" +""" +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + Θ1 = 1 - Θ + # return @.. broadcast=false y₀ + dt*Θ*(k[1] + Θ1*(k[2] + Θ*(k[3]+Θ1*(k[4] + Θ*(k[5] + Θ1*(k[6]+Θ*k[7])))))) + return @inbounds y₀ + + dt * Θ * + (k[1] + + Θ1 * (k[2] + + Θ * (k[3] + Θ1 * (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + Θ1 = 1 - Θ + # return @.. broadcast=false y₀[idxs] + dt*Θ*(k[1][idxs] + Θ1*(k[2][idxs] + Θ*(k[3][idxs]+Θ1*(k[4][idxs] + Θ*(k[5][idxs] + Θ1*(k[6][idxs]+Θ*k[7][idxs])))))) + return y₀[idxs] + + dt * Θ * + (k[1][idxs] + + Θ1 * (k[2][idxs] + + Θ * (k[3][idxs] + + Θ1 * (k[4][idxs] + Θ * (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars::Nothing) + Θ1 = 1 - Θ + @inbounds @.. broadcast=false out=y₀ + + dt * Θ * + (k[1] + + Θ1 * (k[2] + + Θ * (k[3] + + Θ1 * + (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) + #@inbounds for i in eachindex(out) + # out[i] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) + #end + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{0}}, differential_vars::Nothing) + Θ1 = 1 - Θ + @views @.. broadcast=false out=y₀[idxs] + + dt * Θ * + (k[1][idxs] + + Θ1 * (k[2][idxs] + + Θ * (k[3][idxs] + + Θ1 * (k[4][idxs] + + Θ * + (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) + #@inbounds for (j,i) in enumerate(idxs) + # out[j] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) + #end + out +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + @inbounds b1diff = @.. broadcast=false k[1]+k[2] + @inbounds b2diff = @.. broadcast=false -2*k[2]+2*k[3]+2*k[4] + @inbounds b3diff = @.. broadcast=false -3 * k[3]-6 * k[4]+3*k[5]+3*k[6] + @inbounds b4diff = @.. broadcast=false 4 * k[4] - 8 * k[5] - 12 * k[6]+4 * k[7] + @inbounds b5diff = @.. broadcast=false 5 * k[5] + 15 * k[6]-15 * k[7] + @inbounds b6diff = @.. broadcast=false -6 * k[6]+18 * k[7] + @inbounds b7diff = @.. broadcast=false -7*k[7] + # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) + return b1diff + + Θ * + (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + b1diff = @.. broadcast=false k[1][idxs]+k[2][idxs] + b2diff = @.. broadcast=false -2*k[2][idxs]+2*k[3][idxs]+2*k[4][idxs] + b3diff = @.. broadcast=false -3 * k[3][idxs]-6 * k[4][idxs]+3*k[5][idxs]+3*k[6][idxs] + b4diff = @.. broadcast=false 4 * k[4][idxs] - 8 * k[5][idxs] - + 12 * k[6][idxs]+4 * k[7][idxs] + b5diff = @.. broadcast=false 5 * k[5][idxs] + 15 * k[6][idxs]-15 * k[7][idxs] + b6diff = @.. broadcast=false -6 * k[6][idxs]+18 * k[7][idxs] + b7diff = @.. broadcast=false -7*k[7][idxs] + # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) + return b1diff + + Θ * + (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, + T::Type{Val{1}}, differential_vars::Nothing) + # b1diff = k[1] + k[2] + # b2diff = -2*k[2] + 2*k[3] + 2*k[4] + # b3diff = -3*k[3] - 6*k[4] + 3*k[5] + 3*k[6] + # b4diff = 4*k[4] - 8*k[5] - 12*k[6] + 4*k[7] + # b5diff = 5*k[5] + 15*k[6] - 15*k[7] + # b6diff = -6*k[6] + 18*k[7] + # @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + + # Θ*(b5diff + Θ*(b6diff - 7*k[7]*Θ))))) + @views @.. broadcast=false out=k[1] + k[2] + + Θ * (-2 * k[2] + 2 * k[3] + 2 * k[4] + + Θ * (-3 * k[3] - 6 * k[4] + 3 * k[5] + 3 * k[6] + + Θ * (4 * k[4] - 8 * k[5] - 12 * k[6] + 4 * k[7] + + Θ * (5 * k[5] + 15 * k[6] - 15 * k[7] + + Θ * (-6 * k[6] + 18 * k[7] - 7 * k[7] * Θ))))) + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{DP8ConstantCache, DP8Cache}, idxs, + T::Type{Val{1}}, differential_vars::Nothing) + # b1diff = k[1][idxs] + k[2][idxs] + # b2diff = -2*k[2][idxs] + 2*k[3][idxs] + 2*k[4][idxs] + # b3diff = -3*k[3][idxs] - 6*k[4][idxs] + 3*k[5][idxs] + 3*k[6][idxs] + # b4diff = 4*k[4][idxs] - 8*k[5][idxs] - 12*k[6][idxs] + 4*k[7][idxs] + # b5diff = 5*k[5][idxs] + 15*k[6][idxs] - 15*k[7][idxs] + # b6diff = -6*k[6][idxs] + 18*k[7][idxs] + #@views @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + + # Θ*(b5diff + Θ*(b6diff - 7*k[7][idxs]*Θ))))) + @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] + + Θ * (-2 * k[2][idxs] + 2 * k[3][idxs] + 2 * k[4][idxs] + + Θ * + (-3 * k[3][idxs] - 6 * k[4][idxs] + 3 * k[5][idxs] + + 3 * k[6][idxs] + + Θ * + (4 * k[4][idxs] - 8 * k[5][idxs] - 12 * k[6][idxs] + + 4 * k[7][idxs] + + Θ * + (5 * k[5][idxs] + 15 * k[6][idxs] - 15 * k[7][idxs] + + Θ * (-6 * k[6][idxs] + 18 * k[7][idxs] - + 7 * k[7][idxs] * Θ))))) + out +end + +""" +""" diff --git a/src/dense/low_order_rk_addsteps.jl b/src/dense/low_order_rk_addsteps.jl new file mode 100644 index 0000000000..9e609808b1 --- /dev/null +++ b/src/dense/low_order_rk_addsteps.jl @@ -0,0 +1,715 @@ +function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::FunctionMapCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + nothing +end + +function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::FunctionMapConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + nothing +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::OwrenZen4Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 6 || always_calc_begin + uidx = eachindex(uprev) + @unpack k1, k2, k3, k4, k5, k6, tmp = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4 = cache.tab + # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. + a = dt * a21 + @.. broadcast=false tmp=uprev + a * k1 + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + f(k5, tmp, p, t + c4 * dt) + # NOTE: We should not change u here. + @.. broadcast=false tmp=uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + f(k6, tmp, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + copyat_or_push!(k, 5, k5) + copyat_or_push!(k, 6, k6) + end + nothing +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::OwrenZen5Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 8 || always_calc_begin + uidx = eachindex(uprev) + @unpack k1, k2, k3, k4, k5, k6, k7, k8, tmp = cache + @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6 = cache.tab + # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. + a = dt * a21 + @.. broadcast=false tmp=uprev + a * k1 + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + k3) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + f(k6, tmp, p, t + c5 * dt) + @.. broadcast=false tmp=uprev + + dt * + (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + + a76 * k6) + f(k7, tmp, p, t + c6 * dt) + # NOTE: We should not change u here. + @.. broadcast=false tmp=uprev + + dt * + (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + + a87 * k7) + f(k8, tmp, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + copyat_or_push!(k, 5, k5) + copyat_or_push!(k, 6, k6) + copyat_or_push!(k, 7, k7) + copyat_or_push!(k, 8, k8) + end + nothing +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP5Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 4 || always_calc_begin + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract DP5ConstantCacheActual T T2 + @unpack k1, k2, k3, k4, k5, k6, k7, dense_tmp3, dense_tmp4, update, bspl, utilde, tmp, atmp = cache + uidx = eachindex(uprev) + f(k1, uprev, p, t) + @.. broadcast=false tmp=uprev + dt * (a21 * k1) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + f(k6, tmp, p, t + dt) + @.. broadcast=false update=a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6 + @.. broadcast=false tmp=uprev + dt * update + f(k7, tmp, p, t + dt) + copyat_or_push!(k, 1, update) + @.. broadcast=false utilde=dt * (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + btilde7 * k7) + #integrator.k[4] == k5 + @.. broadcast=false k5=d1 * k1 + d3 * k3 + d4 * k4 + d5 * k5 + d6 * k6 + d7 * k7 + #bspl == k3 + @.. broadcast=false bspl=k1 - update + # k6 === integrator.k[3] === k2 + @.. broadcast=false k6=update - k7 - bspl + copyat_or_push!(k, 2, bspl) + copyat_or_push!(k, 3, k6) + copyat_or_push!(k, 4, k5) + end + nothing +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Tsit5Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 7 || always_calc_begin + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 + @unpack k1, k2, k3, k4, k5, k6, k7, tmp = cache + @.. broadcast=false tmp=uprev + dt * (a21 * k1) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + f(k6, tmp, p, t + dt) + @.. broadcast=false tmp=uprev + + dt * + (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + + a76 * k6) + f(k7, tmp, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + copyat_or_push!(k, 5, k5) + copyat_or_push!(k, 6, k6) + copyat_or_push!(k, 7, k7) + end + nothing +end + +""" +An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine +Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 + +Called to add the extra k9, k10, k11 steps for the Order 5 interpolation when needed +""" +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::BS5Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 8 || always_calc_begin + uidx = eachindex(uprev) + @unpack k1, k2, k3, k4, k5, k6, k7, k8, tmp = cache + @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87 = cache.tab + @.. broadcast=false tmp=uprev + dt * a21 * k1 + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + f(k6, tmp, p, t + c5 * dt) + @.. broadcast=false tmp=uprev + + dt * + (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + + a76 * k6) + f(k7, tmp, p, t + dt) + @.. broadcast=false tmp=uprev + + dt * + (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + + a87 * k7) + f(k8, tmp, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + copyat_or_push!(k, 5, k5) + copyat_or_push!(k, 6, k6) + copyat_or_push!(k, 7, k7) + copyat_or_push!(k, 8, k8) + end + if (allow_calc_end && length(k) < 11) || force_calc_end # Have not added the extra stages yet + uidx = eachindex(uprev) + rtmp = similar(cache.k1) + @unpack tmp = cache + @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache.tab + @.. broadcast=false tmp=uprev + + dt * (a91 * k[1] + a92 * k[2] + a93 * k[3] + a94 * k[4] + + a95 * k[5] + a96 * k[6] + a97 * k[7] + a98 * k[8]) + f(rtmp, tmp, p, t + c6 * dt) + copyat_or_push!(k, 9, rtmp) + @.. broadcast=false tmp=uprev + + dt * + (a101 * k[1] + a102 * k[2] + a103 * k[3] + a104 * k[4] + + a105 * k[5] + a106 * k[6] + a107 * k[7] + a108 * k[8] + + a109 * k[9]) + f(rtmp, tmp, p, t + c7 * dt) + copyat_or_push!(k, 10, rtmp) + @.. broadcast=false tmp=uprev + + dt * + (a111 * k[1] + a112 * k[2] + a113 * k[3] + a114 * k[4] + + a115 * k[5] + a116 * k[6] + a117 * k[7] + a118 * k[8] + + a119 * k[9] + a1110 * k[10]) + f(rtmp, tmp, p, t + c8 * dt) + copyat_or_push!(k, 11, rtmp) + end + nothing +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, + cache::OwrenZen3ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 4 || always_calc_begin + @unpack a21, a31, a32, a41, a42, a43, c1, c2 = cache + k1 = f(uprev, p, t) + a1 = dt * a21 + k2 = f(uprev + a1 * k1, p, t + c1 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c2 * dt) + u = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(u, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + end + nothing +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::OwrenZen3Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 4 || always_calc_begin + @unpack k1, k2, k3, k4, tmp = cache + @unpack a21, a31, a32, a41, a42, a43, c1, c2 = cache.tab + # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. + a1 = dt * a21 + @.. broadcast=false tmp=uprev + a1 * k1 + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) + f(k3, tmp, p, t + c2 * dt) + # NOTE: We should not change u here. + @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + f(k4, tmp, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + end + nothing +end + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, + cache::OwrenZen4ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 6 || always_calc_begin + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4 = cache + k1 = f(uprev, p, t) + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + u = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(u, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + copyat_or_push!(k, 5, k5) + copyat_or_push!(k, 6, k6) + end + nothing +end + +#= +@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::OwrenZen4Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) + if length(k)<6 || always_calc_begin + uidx = eachindex(uprev) + @unpack k1,k2,k3,k4,k5,k6,tmp = cache + @unpack a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a63,a64,a65,c1,c2,c3,c4 = cache.tab + # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. + a = dt*a21 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2,tmp,p,t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3,tmp,p,t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) + end + f(k4,tmp,p,t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5,tmp,p,t+c4*dt) + # NOTE: We should not change u here. + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6,tmp,p,t+dt) + copyat_or_push!(k,1,k1) + copyat_or_push!(k,2,k2) + copyat_or_push!(k,3,k3) + copyat_or_push!(k,4,k4) + copyat_or_push!(k,5,k5) + copyat_or_push!(k,6,k6) + end + nothing +end +=# + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, + cache::OwrenZen5ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 8 || always_calc_begin + @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6 = cache + k1 = f(uprev, p, t) + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, + t + c5 * dt) + k7 = f( + uprev + + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), + p, + t + c6 * dt) + u = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) + k8 = f(u, p, t + dt) + copyat_or_push!(k, 1, k1) + copyat_or_push!(k, 2, k2) + copyat_or_push!(k, 3, k3) + copyat_or_push!(k, 4, k4) + copyat_or_push!(k, 5, k5) + copyat_or_push!(k, 6, k6) + copyat_or_push!(k, 7, k7) + copyat_or_push!(k, 8, k8) + end + nothing +end + +#= +@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::OwrenZen5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) + if length(k)<8 || always_calc_begin + uidx = eachindex(uprev) + @unpack k1,k2,k3,k4,k5,k6,k7,k8,tmp = cache + @unpack a21,a31,a32,a41,a42,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,c1,c2,c3,c4,c5,c6 = cache.tab + # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. + a = dt*a21 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2,tmp,p,t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3,tmp,p,t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+k3[i]) + end + f(k4,tmp,p,t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5,tmp,p,t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6,tmp,p,t+c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) + end + f(k7,tmp,p,t+c6*dt) + # NOTE: We should not change u here. + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) + end + f(k8,tmp,p,t+dt) + copyat_or_push!(k,1,k1) + copyat_or_push!(k,2,k2) + copyat_or_push!(k,3,k3) + copyat_or_push!(k,4,k4) + copyat_or_push!(k,5,k5) + copyat_or_push!(k,6,k6) + copyat_or_push!(k,7,k7) + copyat_or_push!(k,8,k8) + end + nothing +end +=# + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP5ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 4 || always_calc_begin + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract DP5ConstantCacheActual T T2 + k1 = f(uprev, p, t) + k2 = f(uprev + dt * (a21 * k1), p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, + t + dt) + update = a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6 + k7 = f(uprev + dt * update, p, t + dt) + copyat_or_push!(k, 1, update) + bspl = k1 - update + copyat_or_push!(k, 2, bspl) + copyat_or_push!(k, 3, update - k7 - bspl) + copyat_or_push!(k, 4, d1 * k1 + d3 * k3 + d4 * k4 + d5 * k5 + d6 * k6 + d7 * k7) + end + nothing +end + +#= +@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::DP5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) + if length(k)<4 || always_calc_begin + @unpack a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a73,a74,a75,a76,btilde1,btilde3,btilde4,btilde5,btilde6,btilde7,c1,c2,c3,c4,c5,c6 = cache.tab + @unpack k1,k2,k3,k4,k5,k6,k7,dense_tmp3,dense_tmp4,update,bspl,utilde,tmp,atmp = cache + @unpack d1,d3,d4,d5,d6,d7 = cache.tab + uidx = eachindex(uprev) + f(k1,uprev,p,t) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a21*k1[i]) + end + f(k2,tmp,p,t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3,tmp,p,t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) + end + f(k4,tmp,p,t+c3*dt) + @tight_loop_macros for i in uidx + tmp[i] =uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5,tmp,p,t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6,tmp,p,t+dt) + @tight_loop_macros for i in uidx + @inbounds update[i] = a71*k1[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i] + @inbounds tmp[i] = uprev[i]+dt*update[i] + end + f(k7,tmp,p,t+dt) + copyat_or_push!(k,1,update) + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i] + btilde6*k6[i] + btilde7*k7[i]) + end + @tight_loop_macros for i in uidx + #integrator.k[4] == k5 + @inbounds k5[i] = d1*k1[i]+d3*k3[i]+d4*k4[i]+d5*k5[i]+d6*k6[i]+d7*k7[i] + #bspl == k3 + @inbounds bspl[i] = k1[i] - update[i] + # k6 === integrator.k[3] === k2 + @inbounds k6[i] = update[i] - k7[i] - bspl[i] + end + copyat_or_push!(k,2,bspl) + copyat_or_push!(k,3,k6) + copyat_or_push!(k,4,k5) + end + nothing +end +=# + +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Tsit5ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 7 || always_calc_begin + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 + copyat_or_push!(k, 1, f(uprev, p, t)) + copyat_or_push!(k, 2, f(uprev + dt * (a21 * k[1]), p, t + c1 * dt)) + copyat_or_push!(k, 3, f(uprev + dt * (a31 * k[1] + a32 * k[2]), p, t + c2 * dt)) + copyat_or_push!(k, 4, + f(uprev + dt * (a41 * k[1] + a42 * k[2] + a43 * k[3]), p, + t + c3 * dt)) + copyat_or_push!(k, 5, + f(uprev + dt * (a51 * k[1] + a52 * k[2] + a53 * k[3] + a54 * k[4]), + p, t + c4 * dt)) + copyat_or_push!(k, 6, + f( + uprev + + dt * + (a61 * k[1] + a62 * k[2] + a63 * k[3] + a64 * k[4] + a65 * k[5]), + p, t + dt)) + utmp = uprev + + dt * + (a71 * k[1] + a72 * k[2] + a73 * k[3] + a74 * k[4] + a75 * k[5] + a76 * k[6]) + copyat_or_push!(k, 7, f(utmp, p, t + dt)) + end + nothing +end + +#= +@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::Tsit5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) + if length(k)<7 || always_calc_begin + @unpack c1,c2,c3,c4,c5,c6,a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76 = cache.tab + @unpack k1,k2,k3,k4,k5,k6,k7,tmp = cache + uidx = eachindex(uprev) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a21*k1[i]) + end + f(k2,tmp,p,t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3,tmp,p,t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) + end + f(k4,tmp,p,t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5,tmp,p,t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6,tmp,p,t+dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) + end + f(k7,u,p,t+dt) + copyat_or_push!(k,1,k1) + copyat_or_push!(k,2,k2) + copyat_or_push!(k,3,k3) + copyat_or_push!(k,4,k4) + copyat_or_push!(k,5,k5) + copyat_or_push!(k,6,k6) + copyat_or_push!(k,7,k7) + end + nothing +end +=# + +""" +An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine +Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 + +Called to add the extra k9, k10, k11 steps for the Order 5 interpolation when needed +""" +@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::BS5ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 8 || always_calc_begin + @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87 = cache + copyat_or_push!(k, 1, f(uprev, p, t)) + copyat_or_push!(k, 2, f(uprev + dt * a21 * k[1], p, t + c1 * dt)) + copyat_or_push!(k, 3, f(uprev + dt * (a31 * k[1] + a32 * k[2]), p, t + c2 * dt)) + copyat_or_push!(k, 4, + f(uprev + dt * (a41 * k[1] + a42 * k[2] + a43 * k[3]), p, + t + c3 * dt)) + copyat_or_push!(k, 5, + f(uprev + dt * (a51 * k[1] + a52 * k[2] + a53 * k[3] + a54 * k[4]), + p, t + c4 * dt)) + copyat_or_push!(k, 6, + f( + uprev + + dt * + (a61 * k[1] + a62 * k[2] + a63 * k[3] + a64 * k[4] + a65 * k[5]), + p, t + c5 * dt)) + copyat_or_push!(k, 7, + f( + uprev + + dt * + (a71 * k[1] + a72 * k[2] + a73 * k[3] + a74 * k[4] + a75 * k[5] + + a76 * k[6]), + p, + t + dt)) + copyat_or_push!(k, 8, + f( + uprev + + dt * + (a81 * k[1] + a83 * k[3] + a84 * k[4] + a85 * k[5] + a86 * k[6] + + a87 * k[7]), + p, + t + dt)) + end + if (allow_calc_end && length(k) < 11) || force_calc_end # Have not added the extra stages yet + @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache + copyat_or_push!(k, 9, + f( + uprev + + dt * + (a91 * k[1] + a92 * k[2] + a93 * k[3] + a94 * k[4] + a95 * k[5] + + a96 * k[6] + a97 * k[7] + a98 * k[8]), + p, + t + c6 * dt)) + copyat_or_push!(k, 10, + f( + uprev + + dt * (a101 * k[1] + a102 * k[2] + a103 * k[3] + a104 * k[4] + + a105 * k[5] + a106 * k[6] + a107 * k[7] + a108 * k[8] + + a109 * k[9]), + p, + t + c7 * dt)) + copyat_or_push!(k, 11, + f( + uprev + + dt * (a111 * k[1] + a112 * k[2] + a113 * k[3] + a114 * k[4] + + a115 * k[5] + a116 * k[6] + a117 * k[7] + a118 * k[8] + + a119 * k[9] + a1110 * k[10]), + p, + t + c8 * dt)) + end + nothing +end + +#= +""" +An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine + Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 + +Called to add the extra k9, k10, k11 steps for the Order 5 interpolation when needed +""" +@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::BS5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) + if length(k) < 8 || always_calc_begin + uidx = eachindex(uprev) + @unpack k1,k2,k3,k4,k5,k6,k7,k8,tmp = cache + @unpack c1,c2,c3,c4,c5,a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87 = cache.tab + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*a21*k1[i] + end + f(k2,tmp,p,t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3,tmp,p,t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) + end + f(k4,tmp,p,t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5,tmp,p,t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6,tmp,p,t+c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) + end + f(k7,tmp,p,t+dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) + end + f(k8,tmp,p,t+dt) + copyat_or_push!(k,1,k1) + copyat_or_push!(k,2,k2) + copyat_or_push!(k,3,k3) + copyat_or_push!(k,4,k4) + copyat_or_push!(k,5,k5) + copyat_or_push!(k,6,k6) + copyat_or_push!(k,7,k7) + copyat_or_push!(k,8,k8) + end + if (allow_calc_end && length(k)< 11) || force_calc_end # Have not added the extra stages yet + uidx = eachindex(uprev) + rtmp = similar(cache.k1) + @unpack tmp = cache + @unpack c6,c7,c8,a91,a92,a93,a94,a95,a96,a97,a98,a101,a102,a103,a104,a105,a106,a107,a108,a109,a111,a112,a113,a114,a115,a116,a117,a118,a119,a1110 = cache.tab + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a91*k[1][i]+a92*k[2][i]+a93*k[3][i]+a94*k[4][i]+a95*k[5][i]+a96*k[6][i]+a97*k[7][i]+a98*k[8][i]) + end + f(rtmp,tmp,p,t+c6*dt); copyat_or_push!(k,9,rtmp) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a101*k[1][i]+a102*k[2][i]+a103*k[3][i]+a104*k[4][i]+a105*k[5][i]+a106*k[6][i]+a107*k[7][i]+a108*k[8][i]+a109*k[9][i]) + end + f(rtmp,tmp,p,t+c7*dt); copyat_or_push!(k,10,rtmp) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a111*k[1][i]+a112*k[2][i]+a113*k[3][i]+a114*k[4][i]+a115*k[5][i]+a116*k[6][i]+a117*k[7][i]+a118*k[8][i]+a119*k[9][i]+a1110*k[10][i]) + end + f(rtmp,tmp,p,t+c8*dt); copyat_or_push!(k,11,rtmp) + end + nothing +end +=# diff --git a/src/dense/rosenbrock_interpolants.jl b/src/dense/rosenbrock_interpolants.jl new file mode 100644 index 0000000000..6f50205cf1 --- /dev/null +++ b/src/dense/rosenbrock_interpolants.jl @@ -0,0 +1,367 @@ +### Fallbacks to capture + +ROSENBROCKS_WITH_INTERPOLATIONS = Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache, + Rodas23WConstantCache, Rodas3PConstantCache, + Rodas23WCache, Rodas3PCache, + Rodas4ConstantCache, Rosenbrock5ConstantCache, + Rodas4Cache, Rosenbrock5Cache} + +function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::ROSENBROCKS_WITH_INTERPOLATIONS, + idxs, T::Type{Val{D}}, differential_vars) where {D} + throw(DerivativeOrderNotPossibleError()) +end + +function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::ROSENBROCKS_WITH_INTERPOLATIONS, + idxs, T::Type{Val{D}}, differential_vars) where {D} + throw(DerivativeOrderNotPossibleError()) +end + +#### + +""" +From MATLAB ODE Suite by Shampine +""" +@def rosenbrock2332unpack begin + if cache isa OrdinaryDiffEqMutableCache + d = cache.tab.d + else + d = cache.d + end +end + +@def rosenbrock2332pre0 begin + @rosenbrock2332unpack + c1 = Θ * (1 - Θ) / (1 - 2d) + c2 = Θ * (Θ - 2d) / (1 - 2d) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, + Rosenbrock32ConstantCache}, idxs::Nothing, + T::Type{Val{0}}, differential_vars) + @rosenbrock2332pre0 + @inbounds y₀ + dt * (c1 * k[1] + c2 * k[2]) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23Cache, Rosenbrock32Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars) + @rosenbrock2332pre0 + @inbounds @.. broadcast=false y₀+dt * (c1 * k[1] + c2 * k[2]) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache + }, idxs, T::Type{Val{0}}, differential_vars) + @rosenbrock2332pre0 + @.. broadcast=false y₀[idxs]+dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, + Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache + }, idxs::Nothing, T::Type{Val{0}}, differential_vars) + @rosenbrock2332pre0 + @inbounds @.. broadcast=false out=y₀ + dt * (c1 * k[1] + c2 * k[2]) + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, + Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache + }, idxs, T::Type{Val{0}}, differential_vars) + @rosenbrock2332pre0 + @views @.. broadcast=false out=y₀[idxs] + dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) + out +end + +# First Derivative of the dense output +@def rosenbrock2332pre1 begin + @rosenbrock2332unpack + c1diff = (1 - 2 * Θ) / (1 - 2 * d) + c2diff = (2 * Θ - 2 * d) / (1 - 2 * d) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache + }, idxs::Nothing, T::Type{Val{1}}, differential_vars) + @rosenbrock2332pre1 + @.. broadcast=false c1diff * k[1]+c2diff * k[2] +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache + }, idxs, T::Type{Val{1}}, differential_vars) + @rosenbrock2332pre1 + @.. broadcast=false c1diff * k[1][idxs]+c2diff * k[2][idxs] +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, + Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache + }, idxs::Nothing, T::Type{Val{1}}, differential_vars) + @rosenbrock2332pre1 + @.. broadcast=false out=c1diff * k[1] + c2diff * k[2] + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock23ConstantCache, + Rosenbrock23Cache, + Rosenbrock32ConstantCache, Rosenbrock32Cache + }, idxs, T::Type{Val{1}}, differential_vars) + @rosenbrock2332pre1 + @views @.. broadcast=false out=c1diff * k[1][idxs] + c2diff * k[2][idxs] + out +end + +""" +From MATLAB ODE Suite by Shampine +""" +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @inbounds Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) +end + +@muladd function _ode_interpolant( + Θ, dt, y₀, y₁, k, cache::Union{Rodas4Cache, Rodas23WCache, Rodas3PCache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @inbounds @.. broadcast=false Θ1 * y₀+Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, + Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, + idxs, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @.. broadcast=false Θ1 * y₀[idxs]+Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, + Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @.. broadcast=false out=Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, + Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, + idxs, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @views @.. broadcast=false out=Θ1 * y₀[idxs] + + Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) + out +end + +# First Derivative +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars) + @inbounds (k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁) / dt +end + +@muladd function _ode_interpolant( + Θ, dt, y₀, y₁, k, cache::Union{Rodas4Cache, Rodas23WCache, Rodas3PCache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars) + @inbounds @.. broadcast=false (k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + + y₁)/dt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, + Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, + idxs, T::Type{Val{1}}, differential_vars) + @.. broadcast=false (k[1][idxs] + + Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] - 3 * k[2][idxs] * Θ) - + y₀[idxs] + y₁[idxs])/dt +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, + Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars) + @.. broadcast=false out=(k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁) / + dt + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, + Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, + idxs, T::Type{Val{1}}, differential_vars) + @views @.. broadcast=false out=(k[1][idxs] + + Θ * + (-2 * k[1][idxs] + 2 * k[2][idxs] - + 3 * k[2][idxs] * Θ) - + y₀[idxs] + y₁[idxs]) / dt + out +end + +#- + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, + idxs::Nothing, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @inbounds Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, + T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @inbounds @.. broadcast=false Θ1 * y₀+Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @.. broadcast=false Θ1 * + y₀[idxs]+Θ * (y₁[idxs] + + Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs::Nothing, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @.. broadcast=false out=Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{0}}, differential_vars) + Θ1 = 1 - Θ + @views @.. broadcast=false out=Θ1 * y₀[idxs] + + Θ * (y₁[idxs] + + Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) + out +end + +# First Derivative +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, + idxs::Nothing, T::Type{Val{1}}, differential_vars) + @inbounds (k[1] + + Θ * (-2 * k[1] + 2 * k[2] + Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + + y₁) / dt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, + T::Type{Val{1}}, differential_vars) + @inbounds @.. broadcast=false (k[1] + + Θ * (-2 * k[1] + 2 * k[2] + + Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + y₁)/dt +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{1}}, differential_vars) + @.. broadcast=false (k[1][idxs] + + Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] + + Θ * (-3 * k[2][idxs] + 3 * k[3][idxs] - 4 * Θ * k[3][idxs])) - + y₀[idxs] + y₁[idxs])/dt +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs::Nothing, T::Type{Val{1}}, differential_vars) + @.. broadcast=false out=(k[1] + + Θ * (-2 * k[1] + 2 * k[2] + + Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + y₁) / dt + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{1}}, differential_vars) + @views @.. broadcast=false out=(k[1][idxs] + + Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] + + Θ * + (-3 * k[2][idxs] + 3 * k[3][idxs] - 4 * Θ * k[3][idxs])) - + y₀[idxs] + y₁[idxs]) / dt + out +end + +# Second Derivative +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, + idxs::Nothing, T::Type{Val{2}}, differential_vars) + @inbounds (-2 * k[1] + 2 * k[2] + Θ * (-6 * k[2] + 6 * k[3] - 12 * Θ * k[3])) / dt^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, + T::Type{Val{2}}, differential_vars) + @inbounds @.. broadcast=false (-2 * k[1] + 2 * k[2] + + Θ * (-6 * k[2] + 6 * k[3] - 12 * Θ * k[3]))/dt^2 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{2}}, differential_vars) + @.. broadcast=false (-2 * k[1][idxs] + 2 * k[2][idxs] + + Θ * (-6 * k[2][idxs] + 6 * k[3][idxs] - 12 * Θ * k[3][idxs]))/dt^2 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs::Nothing, T::Type{Val{2}}, differential_vars) + @.. broadcast=false out=(-2 * k[1] + 2 * k[2] + + Θ * (-6 * k[2] + 6 * k[3] - 12 * Θ * k[3])) / dt^2 + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{2}}, differential_vars) + @views @.. broadcast=false out=(-2 * k[1][idxs] + 2 * k[2][idxs] + + Θ * + (-6 * k[2][idxs] + 6 * k[3][idxs] - 12 * Θ * k[3][idxs])) / + dt^2 + out +end + +# Third Derivative +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, + idxs::Nothing, T::Type{Val{3}}, differential_vars) + @inbounds (-6 * k[2] + 6 * k[3] - 24 * Θ * k[3]) / dt^3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, + T::Type{Val{3}}, differential_vars) + @inbounds @.. broadcast=false (-6 * k[2] + 6 * k[3] - 24 * Θ * k[3])/dt^3 +end + +@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{3}}, differential_vars) + @.. broadcast=false (-6 * k[2][idxs] + 6 * k[3][idxs] - 24 * Θ * k[3][idxs])/dt^3 +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs::Nothing, T::Type{Val{3}}, differential_vars) + @.. broadcast=false out=(-6 * k[2] + 6 * k[3] - 24 * Θ * k[3]) / dt^3 + out +end + +@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, + cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, + idxs, T::Type{Val{3}}, differential_vars) + @views @.. broadcast=false out=(-6 * k[2][idxs] + 6 * k[3][idxs] - + 24 * Θ * k[3][idxs]) / dt^3 + out +end diff --git a/src/dense/stiff_addsteps.jl b/src/dense/stiff_addsteps.jl new file mode 100644 index 0000000000..6e77125e14 --- /dev/null +++ b/src/dense/stiff_addsteps.jl @@ -0,0 +1,837 @@ +function _ode_addsteps!(k, t, uprev, u, dt, f, p, + cache::Union{Rosenbrock23ConstantCache, + Rosenbrock32ConstantCache}, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 2 || always_calc_begin + @unpack tf, uf, d = cache + γ = dt * d + tf.u = uprev + if cache.autodiff isa AutoForwardDiff + dT = ForwardDiff.derivative(tf, t) + else + dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) + end + + mass_matrix = f.mass_matrix + if uprev isa AbstractArray + J = ForwardDiff.jacobian(uf, uprev) + W = mass_matrix - γ * J + else + J = ForwardDiff.derivative(uf, uprev) + W = 1 - γ * J + end + k₁ = W \ (f(uprev, p, t) + dt * d * dT) + f₁ = f(uprev + dt * k₁ / 2, p, t + dt / 2) + k₂ = W \ (f₁ - k₁) + k₁ + copyat_or_push!(k, 1, k₁) + copyat_or_push!(k, 2, k₂) + end + nothing +end + +function _ode_addsteps!(k, t, uprev, u, dt, f, p, + cache::Union{Rosenbrock23Cache, Rosenbrock32Cache}, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 2 || always_calc_begin + @unpack k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, tmp, uf, tf, linsolve_tmp, weight = cache + @unpack c₃₂, d = cache.tab + uidx = eachindex(uprev) + + # Assignments + sizeu = size(u) + mass_matrix = f.mass_matrix + γ = dt * d + dto2 = dt / 2 + dto6 = dt / 6 + + @.. broadcast=false linsolve_tmp=@muladd fsalfirst + γ * dT + + ### Jacobian does not need to be re-evaluated after an event + ### Since it's unchanged + jacobian2W!(W, mass_matrix, γ, J, false) + + linsolve = cache.linsolve + + linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), + reltol = cache.reltol) + + vecu = _vec(linres.u) + veck₁ = _vec(k₁) + + @.. broadcast=false veck₁=-vecu + + @.. broadcast=false tmp=uprev + dto2 * k₁ + f(f₁, tmp, p, t + dto2) + + if mass_matrix === I + tmp .= k₁ + else + mul!(_vec(tmp), mass_matrix, _vec(k₁)) + end + + @.. broadcast=false linsolve_tmp=f₁ - tmp + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck2 = _vec(k₂) + + @.. broadcast=false veck2=-vecu + + @.. broadcast=false k₂+=k₁ + + copyat_or_push!(k, 1, k₁) + copyat_or_push!(k, 2, k₂) + cache.linsolve = linres.cache + end + nothing +end + +function _ode_addsteps!( + k, t, uprev, u, dt, f, p, cache::Union{Rodas23WConstantCache, Rodas3PConstantCache}, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 2 || always_calc_begin + @unpack tf, uf = cache + @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtgamma = dt * gamma + mass_matrix = f.mass_matrix + + # Time derivative + tf.u = uprev + if cache.autodiff isa AutoForwardDiff + dT = ForwardDiff.derivative(tf, t) + else + dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) + end + + # Jacobian + uf.t = t + if uprev isa AbstractArray + J = ForwardDiff.jacobian(uf, uprev) + W = mass_matrix / dtgamma - J + else + J = ForwardDiff.derivative(uf, uprev) + W = 1 / dtgamma - J + end + + du = f(uprev, p, t) + k3 = copy(du) + + linsolve_tmp = du + dtd1 * dT + + k1 = W \ linsolve_tmp + u = uprev + a21 * k1 + du = f(u, p, t + c2 * dt) + + linsolve_tmp = du + dtd2 * dT + dtC21 * k1 + + k2 = W \ linsolve_tmp + + linsolve_tmp = k3 + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + + k3 = W \ linsolve_tmp + u = uprev + a41 * k1 + a42 * k2 + a43 * k3 + du = f(u, p, t + dt) + + linsolve_tmp = du + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + + k4 = W \ linsolve_tmp + + linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + + k5 = W \ linsolve_tmp + + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab + k₁ = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + k₂ = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + #k₃ = h2_21 * k1 + h2_22 * k2 + h2_23 * k3 + h2_24 * k4 + h2_25 * k5 + copyat_or_push!(k, 1, k₁) + copyat_or_push!(k, 2, k₂) + #copyat_or_push!(k, 3, k₃) + end + nothing +end + +function _ode_addsteps!( + k, t, uprev, u, dt, f, p, cache::Union{Rodas23WCache, Rodas3PCache}, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 2 || always_calc_begin + @unpack du, du1, du2, tmp, k1, k2, k3, k4, k5, dT, J, W, uf, tf, linsolve_tmp, jac_config, fsalfirst, weight = cache + @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab + + # Assignments + sizeu = size(u) + uidx = eachindex(uprev) + mass_matrix = f.mass_matrix + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtgamma = dt * gamma + + @.. broadcast=false linsolve_tmp=@muladd fsalfirst + dtgamma * dT + + ### Jacobian does not need to be re-evaluated after an event + ### Since it's unchanged + jacobian2W!(W, mass_matrix, dtgamma, J, true) + + linsolve = cache.linsolve + + linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck1 = _vec(k1) + + @.. broadcast=false veck1=-vecu + @.. broadcast=false tmp=uprev + a21 * k1 + f(du, tmp, p, t + c2 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck2 = _vec(k2) + @.. broadcast=false veck2=-vecu + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=fsalfirst + dtd3 * dT + + (dtC31 * k1 + dtC32 * k2) + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=fsalfirst + dtd3 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck3 = _vec(k3) + @.. broadcast=false veck3=-vecu + @.. broadcast=false tmp=uprev + a41 * k1 + a42 * k2 + a43 * k3 + f(du, tmp, p, t + dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck4 = _vec(k4) + @.. broadcast=false veck4=-vecu + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + + dtC53 * k3) + else + @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck5 = _vec(k5) + @.. broadcast=false veck5=-vecu + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab + @.. broadcast=false du=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + copyat_or_push!(k, 1, copy(du)) + + @.. broadcast=false du=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + copyat_or_push!(k, 2, copy(du)) + end + nothing +end + +function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rodas4ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 2 || always_calc_begin + @unpack tf, uf = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtgamma = dt * gamma + mass_matrix = f.mass_matrix + + # Time derivative + tf.u = uprev + if cache.autodiff isa AutoForwardDiff + dT = ForwardDiff.derivative(tf, t) + else + dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) + end + + # Jacobian + uf.t = t + if uprev isa AbstractArray + J = ForwardDiff.jacobian(uf, uprev) + W = mass_matrix / dtgamma - J + else + J = ForwardDiff.derivative(uf, uprev) + W = 1 / dtgamma - J + end + + du = f(uprev, p, t) + + linsolve_tmp = du + dtd1 * dT + + k1 = W \ linsolve_tmp + u = uprev + a21 * k1 + du = f(u, p, t + c2 * dt) + + linsolve_tmp = du + dtd2 * dT + dtC21 * k1 + + k2 = W \ linsolve_tmp + u = uprev + a31 * k1 + a32 * k2 + du = f(u, p, t + c3 * dt) + + linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + + k3 = W \ linsolve_tmp + u = uprev + a41 * k1 + a42 * k2 + a43 * k3 + du = f(u, p, t + c4 * dt) + + linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + + k4 = W \ linsolve_tmp + u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + du = f(u, p, t + dt) + + linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + + k5 = W \ linsolve_tmp + + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab + k₁ = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + k₂ = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + copyat_or_push!(k, 1, k₁) + copyat_or_push!(k, 2, k₂) + end + nothing +end + +function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rodas4Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 2 || always_calc_begin + @unpack du, du1, du2, tmp, k1, k2, k3, k4, k5, k6, dT, J, W, uf, tf, linsolve_tmp, jac_config, fsalfirst, weight = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab + + # Assignments + sizeu = size(u) + uidx = eachindex(uprev) + mass_matrix = f.mass_matrix + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtgamma = dt * gamma + + @.. broadcast=false linsolve_tmp=@muladd fsalfirst + dtgamma * dT + + ### Jacobian does not need to be re-evaluated after an event + ### Since it's unchanged + jacobian2W!(W, mass_matrix, dtgamma, J, true) + + linsolve = cache.linsolve + + linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck1 = _vec(k1) + + @.. broadcast=false veck1=-vecu + @.. broadcast=false tmp=uprev + a21 * k1 + f(du, tmp, p, t + c2 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck2 = _vec(k2) + @.. broadcast=false veck2=-vecu + @.. broadcast=false tmp=uprev + a31 * k1 + a32 * k2 + f(du, tmp, p, t + c3 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck3 = _vec(k3) + @.. broadcast=false veck3=-vecu + @.. broadcast=false tmp=uprev + a41 * k1 + a42 * k2 + a43 * k3 + f(du, tmp, p, t + c4 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck4 = _vec(k4) + @.. broadcast=false veck4=-vecu + @.. broadcast=false tmp=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + f(du, tmp, p, t + dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + + dtC53 * k3) + else + @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck5 = _vec(k5) + @.. broadcast=false veck5=-vecu + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab + @.. broadcast=false k6=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + copyat_or_push!(k, 1, copy(k6)) + + @.. broadcast=false k6=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + copyat_or_push!(k, 2, copy(k6)) + end + nothing +end + +function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rosenbrock5ConstantCache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 3 || always_calc_begin + @unpack tf, uf = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + dtC71 = C71 / dt + dtC72 = C72 / dt + dtC73 = C73 / dt + dtC74 = C74 / dt + dtC75 = C75 / dt + dtC76 = C76 / dt + dtC81 = C81 / dt + dtC82 = C82 / dt + dtC83 = C83 / dt + dtC84 = C84 / dt + dtC85 = C85 / dt + dtC86 = C86 / dt + dtC87 = C87 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtd5 = dt * d5 + dtgamma = dt * gamma + mass_matrix = f.mass_matrix + + # Time derivative + tf.u = uprev + # if cache.autodiff isa AutoForwardDiff + # dT = ForwardDiff.derivative(tf, t) + # else + dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) + # end + + # Jacobian + uf.t = t + if uprev isa AbstractArray + J = ForwardDiff.jacobian(uf, uprev) + W = mass_matrix / dtgamma - J + else + J = ForwardDiff.derivative(uf, uprev) + W = 1 / dtgamma - J + end + + du = f(uprev, p, t) + + linsolve_tmp = du + dtd1 * dT + + k1 = W \ linsolve_tmp + u = uprev + a21 * k1 + du = f(u, p, t + c2 * dt) + + linsolve_tmp = du + dtd2 * dT + dtC21 * k1 + + k2 = W \ linsolve_tmp + u = uprev + a31 * k1 + a32 * k2 + du = f(u, p, t + c3 * dt) + + linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + + k3 = W \ linsolve_tmp + u = uprev + a41 * k1 + a42 * k2 + a43 * k3 + du = f(u, p, t + c4 * dt) + + linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + + k4 = W \ linsolve_tmp + u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + du = f(u, p, t + c5 * dt) + + linsolve_tmp = du + dtd5 * dT + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + + k5 = W \ linsolve_tmp + u = uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 + du = f(u, p, t + dt) + + linsolve_tmp = du + (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + dtC65 * k5) + + k6 = W \ linsolve_tmp + u = u + k6 + du = f(u, p, t + dt) + + linsolve_tmp = du + + (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + dtC75 * k5 + + dtC76 * k6) + + k7 = W \ linsolve_tmp + + u = u + k7 + du = f(u, p, t + dt) + + linsolve_tmp = du + + (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + dtC85 * k5 + + dtC86 * k6 + dtC87 * k7) + + k8 = W \ linsolve_tmp + + @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab + k₁ = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + h26 * k6 + h27 * k7 + + h28 * k8 + k₂ = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + h36 * k6 + h37 * k7 + + h38 * k8 + k₃ = h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + h45 * k5 + h46 * k6 + h47 * k7 + + h48 * k8 + copyat_or_push!(k, 1, k₁) + copyat_or_push!(k, 2, k₂) + copyat_or_push!(k, 3, k₃) + end + nothing +end + +function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rosenbrock5Cache, + always_calc_begin = false, allow_calc_end = true, + force_calc_end = false) + if length(k) < 3 || always_calc_begin + @unpack du, du1, du2, tmp, k1, k2, k3, k4, k5, k6, k7, k8, dT, J, W, uf, tf, linsolve_tmp, jac_config, fsalfirst, weight = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab + + # Assignments + sizeu = size(u) + uidx = eachindex(uprev) + mass_matrix = f.mass_matrix + tmp = k8 # integrator.tmp === linsolve_tmp, aliasing fails due to linsolve mutation + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + dtC71 = C71 / dt + dtC72 = C72 / dt + dtC73 = C73 / dt + dtC74 = C74 / dt + dtC75 = C75 / dt + dtC76 = C76 / dt + dtC81 = C81 / dt + dtC82 = C82 / dt + dtC83 = C83 / dt + dtC84 = C84 / dt + dtC85 = C85 / dt + dtC86 = C86 / dt + dtC87 = C87 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtd5 = dt * d5 + dtgamma = dt * gamma + + @.. broadcast=false linsolve_tmp=@muladd fsalfirst + dtgamma * dT + + ### Jacobian does not need to be re-evaluated after an event + ### Since it's unchanged + jacobian2W!(W, mass_matrix, dtgamma, J, true) + + linsolve = cache.linsolve + + linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck1 = _vec(k1) + + @.. broadcast=false veck1=-vecu + @.. broadcast=false tmp=uprev + a21 * k1 + f(du, tmp, p, t + c2 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck2 = _vec(k2) + @.. broadcast=false veck2=-vecu + @.. broadcast=false tmp=uprev + a31 * k1 + a32 * k2 + f(du, tmp, p, t + c3 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck3 = _vec(k3) + @.. broadcast=false veck3=-vecu + @.. broadcast=false tmp=uprev + a41 * k1 + a42 * k2 + a43 * k3 + f(du, tmp, p, t + c4 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck4 = _vec(k4) + @.. broadcast=false veck4=-vecu + @.. broadcast=false tmp=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + f(du, tmp, p, t + c5 * dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd5 * dT + + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + + dtC53 * k3) + else + @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + dtd5 * dT + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck5 = _vec(k5) + @.. broadcast=false veck5=-vecu + @.. broadcast=false tmp=uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 + f(du, tmp, p, t + dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC62 * k2 + dtC64 * k4 + dtC61 * k1 + + dtC63 * k3 + dtC65 * k5) + else + @.. broadcast=false du1=dtC62 * k2 + dtC64 * k4 + dtC61 * k1 + dtC63 * k3 + + dtC65 * k5 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck6 = _vec(k6) + @.. broadcast=false veck6=-vecu + @.. broadcast=false tmp+=k6 + f(du, tmp, p, t + dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + + dtC74 * k4 + dtC75 * k5 + dtC76 * k6) + else + @.. broadcast=false du1=dtC72 * k2 + dtC74 * k4 + dtC71 * k1 + dtC73 * k3 + + dtC75 * k5 + dtC76 * k6 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck7 = _vec(k7) + @.. broadcast=false veck7=-vecu + @.. broadcast=false tmp+=k7 + f(du, tmp, p, t + dt) + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + + dtC84 * k4 + dtC85 * k5 + dtC86 * k6 + + dtC87 * k7) + else + @.. broadcast=false du1=dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + + dtC85 * k5 + dtC86 * k6 + dtC87 * k7 + mul!(du2, mass_matrix, du1) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), + reltol = cache.reltol) + vecu = _vec(linres.u) + veck8 = _vec(k8) + @.. broadcast=false veck8=-vecu + + # https://github.com/SciML/OrdinaryDiffEq.jl/issues/2055 + tmp = linsolve_tmp + + @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab + @.. broadcast=false tmp=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + + h26 * k6 + h27 * k7 + h28 * k8 + copyat_or_push!(k, 1, copy(tmp)) + + @.. broadcast=false tmp=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + + h36 * k6 + h37 * k7 + h38 * k8 + copyat_or_push!(k, 2, copy(tmp)) + + @.. broadcast=false tmp=h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + h45 * k5 + + h46 * k6 + h47 * k7 + h48 * k8 + copyat_or_push!(k, 3, copy(tmp)) + end + nothing +end diff --git a/src/doc_utils.jl b/src/doc_utils.jl index aa36057812..e5b5681067 100644 --- a/src/doc_utils.jl +++ b/src/doc_utils.jl @@ -55,34 +55,34 @@ function generic_solver_docstring(description::String, end function rosenbrock_docstring(description::String, - name::String; - references::String = "", - extra_keyword_description = "", - extra_keyword_default = "", - with_step_limiter = false) -keyword_default = """ -autodiff = Val{true}(), -concrete_jac = nothing, -linsolve = nothing, -precs = DEFAULT_PRECS, -""" * extra_keyword_default - -keyword_default_description = """ -- `autodiff`: boolean to control if the Jacobian should be computed via AD or not -- `concrete_jac`: function of the form `jac!(J, u, p, t)` -- `linsolve`: custom solver for the inner linear systems -- `precs`: custom preconditioner for the inner linear solver -""" * extra_keyword_description - -if with_step_limiter - keyword_default *= "step_limiter! = OrdinaryDiffEq.trivial_limiter!,\n" - keyword_default_description *= "- `step_limiter!`: function of the form `limiter!(u, integrator, p, t)`\n" -end + name::String; + references::String = "", + extra_keyword_description = "", + extra_keyword_default = "", + with_step_limiter = false) + keyword_default = """ + autodiff = Val{true}(), + concrete_jac = nothing, + linsolve = nothing, + precs = DEFAULT_PRECS, + """ * extra_keyword_default -generic_solver_docstring( - description, name, "Rosenbrock Method. ", references, - keyword_default_description, keyword_default -) + keyword_default_description = """ + - `autodiff`: boolean to control if the Jacobian should be computed via AD or not + - `concrete_jac`: function of the form `jac!(J, u, p, t)` + - `linsolve`: custom solver for the inner linear systems + - `precs`: custom preconditioner for the inner linear solver + """ * extra_keyword_description + + if with_step_limiter + keyword_default *= "step_limiter! = OrdinaryDiffEq.trivial_limiter!,\n" + keyword_default_description *= "- `step_limiter!`: function of the form `limiter!(u, integrator, p, t)`\n" + end + + generic_solver_docstring( + description, name, "Rosenbrock Method. ", references, + keyword_default_description, keyword_default + ) end function explicit_rk_docstring(description::String, diff --git a/src/generic_rosenbrock.jl b/src/generic_rosenbrock.jl new file mode 100644 index 0000000000..32330c27e1 --- /dev/null +++ b/src/generic_rosenbrock.jl @@ -0,0 +1,1810 @@ +#! format: off + +abstract type RosenbrockTableau{T,T2} end +struct RosenbrockFixedTableau{T,T2}<:RosenbrockTableau{T,T2} + a::Array{T,2} + C::Array{T,2} + b::Array{T,1} + gamma::T2 + d::Array{T,1} + c::Array{T2,1} +end + +struct RosenbrockAdaptiveTableau{T,T2}<:RosenbrockTableau{T,T2} + a::Array{T,2} + C::Array{T,2} + b::Array{T,1} + btilde::Array{T,1} + gamma::T2 + d::Array{T,1} + c::Array{T2,1} +end + +""" + @_bitarray2boolarray RosenbrockTableau(tab.a.!=0,...) + +Transform BitArray (in the form of `xs.!=0` ) into 1D-Array of Bools by +`[i for i in xs.!=0]` to satisfy the type constraint of RosenbrockTableau +""" +macro _bitarray2boolarray(expr) + args=[:([i for i in $arg]) for arg in expr.args[2:end]] + args[end-2]=:(tab.gamma!=0) + esc(:($(expr.args[1])($(args...)))) +end + +""" + _masktab(tab) + +Convert normal tableau into a dummy tableau consisting of Bools. We use dummy tableaus +where we only care about whether values in the tableau are zeros. +""" +_masktab(tab::RosenbrockFixedTableau)=@_bitarray2boolarray RosenbrockFixedTableau(tab.a.!=0,tab.C.!=0,tab.b.!=0,tab.gamma!=0,tab.d.!=0,tab.c.!=0) +_masktab(tab::RosenbrockAdaptiveTableau)=@_bitarray2boolarray RosenbrockAdaptiveTableau(tab.a.!=0,tab.C.!=0,tab.b.!=0,tab.btilde.!=0,tab.gamma!=0,tab.d.!=0,tab.c.!=0) + + +""" + _common_nonzero_vals(tab::RosenbrockTableau) + +Return the common nonzero symbols in the tableau. Typical return value: +`[[:a21,:a31,:a32],[:C21,:C31,:C32],[:b1,:b2,:b3],:gamma,[:d1,:d2,:d3],[:c1,:c2,:c3]]` +""" +function _common_nonzero_vals(tab::RosenbrockTableau) + nzvals=[] + push!(nzvals,[Symbol(:a,ind[1],ind[2]) for ind in findall(!iszero,tab.a)]) + push!(nzvals,[Symbol(:C,ind[1],ind[2]) for ind in findall(!iszero,tab.C)]) + push!(nzvals,[Symbol(:b,ind) for ind in findall(!iszero,tab.b)]) + push!(nzvals,:gamma) + push!(nzvals,[Symbol(:d,ind) for ind in findall(!iszero,tab.d)]) + push!(nzvals,[Symbol(:c,ind) for ind in findall(!iszero,tab.c)]) + nzvals +end + +""" + _nonzero_vals(tab::RosenbrockFixedTableau) + +Return all the nonzero symbols in the tableau. Typical return value: +`[:a21,:a31,:a32,:C21,:C31,:C32,:b1,:b2,:b3,:gamma,:d1,:d2,:d3,:c1,:c2,:c3]` +""" +function _nonzero_vals(tab::RosenbrockFixedTableau) + nzvals=_common_nonzero_vals(tab) + vcat(nzvals...) +end + +""" + _nonzero_vals(tab::RosenbrockAdaptiveTableau) + +Typical return value: +`[:a21,:a31,:a32,:C21,:C31,:C32,:b1,:b2,:b3,:btilde1,:btilde2,:btilde3,:gamma,:d1,:d2,:d3,:c1,:c2,:c3]` +""" +function _nonzero_vals(tab::RosenbrockAdaptiveTableau) + nzvals=_common_nonzero_vals(tab) + push!(nzvals,[Symbol(:btilde,ind) for ind in findall(!iszero,tab.btilde)]) + vcat(nzvals...) +end + +""" + _push_assigns!(valexprs,inds,name,type) + +Insert a series of field statements like `[:(c2::T2),:(c3::T2)]` into the array `valexprs`. + +# Arguments +- `valexpr::Array{Expr,1}`: the array to be inserted +- `inds`: an iterator that gives indices +- `name::Symbol`: the prefix name of the values +- `type::Symbol`: type in the statements +""" +function _push_assigns!(valexprs,inds,name,type::Symbol) + for ind in inds + push!(valexprs,:($(Symbol(name,"$(Tuple(ind)...)"))::$type)) + end +end + +""" + gen_tableau_struct(tab::RosenbrockTableau,tabstructname::Symbol) + +Generate the tableau struct expression from a given tableau emulating those in +`tableaus/rosenbrock_tableaus.jl`. The statements of `aij`,`Cij` and `ci` are generated +according to the nonzero values of `tab.a`,`tab.C` and `tab.c` while others are generated +from their indices. One may choose to pass in a dummy tableau with type `<:RosenbrockTalbeau{Bool,Bool}` +to fully control the tableau struct. +""" +function gen_tableau_struct(tab::RosenbrockTableau,tabstructname::Symbol) + valexprs=Array{Expr,1}() + _push_assigns!(valexprs,findall(!iszero,tab.a),:a,:T) + _push_assigns!(valexprs,findall(!iszero,tab.C),:C,:T) + _push_assigns!(valexprs,eachindex(tab.b),:b,:T) + if typeof(tab)<:RosenbrockAdaptiveTableau + _push_assigns!(valexprs,eachindex(tab.btilde),:btilde,:T) + end + push!(valexprs,:(gamma::T2)) + _push_assigns!(valexprs,eachindex(tab.d),:d,:T) + _push_assigns!(valexprs,findall(!iszero,tab.c),:c,:T2) + quote struct $tabstructname{T,T2} + $(valexprs...) + end + end +end + +""" + gen_tableau(tab::RosenbrockTableau,tabstructexpr::Expr,tabname::Symbol) + +Generate the tableau function expression emulating those in `tableaus/rosenbrock_tableaus.jl`. +It takes in the tableau struct expression (generated by gen_tableau_struct(...) or written by hand) +to make sure the actual values of the tableau are organized in the right order. +""" +function gen_tableau(tab::RosenbrockTableau,tabstructexpr::Expr,tabname::Symbol) + @capture(tabstructexpr, struct T_ fields__ end) || error("incorrect tableau expression") + tabstructname = namify(T) + valsym2tabdict=Dict("a"=>tab.a,"C"=>tab.C,"gamma"=>tab.gamma,"c"=>tab.c,"d"=>tab.d,"b"=>tab.b) + if typeof(tab)<:RosenbrockAdaptiveTableau + valsym2tabdict["btilde"]=tab.btilde + end + pattern=r"^([a-zA-Z]+)([1-9]{0,2})$" + assignexprs = Expr[] + valsyms = Symbol[] + for field in fields + if @capture(field, valsym_Symbol::valtype_) + push!(valsyms, valsym) + m = match(pattern, String(valsym)) + val = valsym2tabdict[m[1]][(parse(Int, i) for i in m[2])...] + push!(assignexprs, :($valsym = convert($valtype, $val))) + end + end + quote function $tabname(T, T2) + $(assignexprs...) + $tabstructname($(valsyms...)) + end + end +end + +""" + gen_cache_struct(tab::RosenbrockTableau,cachename::Symbol,constcachename::Symbol) + +Generate cache struct expression emulating those in `caches/rosenbrock_caches.jl`. +The length of k1,k2,... in the mutable cache struct is determined by the length of `tab.b` +because in the end of Rosenbrock's method, we have: `y_{n+1}=y_n+ki*bi`. +""" +function gen_cache_struct(tab::RosenbrockTableau,cachename::Symbol,constcachename::Symbol) + kstype=[:($(Symbol(:k,i))::rateType) for i in 1:length(tab.b)] + constcacheexpr=quote struct $constcachename{TF,UF,Tab,JType,WType,F} <: OrdinaryDiffEqConstantCache + tf::TF + uf::UF + tab::Tab + J::JType + W::WType + linsolve::F + end + end + cacheexpr=quote + @cache mutable struct $cachename{uType,rateType,uNoUnitsType,JType,WType,TabType,TFType,UFType,F,JCType,GCType} <: RosenbrockMutableCache + u::uType + uprev::uType + du::rateType + du1::rateType + du2::rateType + $(kstype...) + fsalfirst::rateType + fsallast::rateType + dT::rateType + J::JType + W::WType + tmp::rateType + atmp::uNoUnitsType + weight::uNoUnitsType + tab::TabType + tf::TFType + uf::UFType + linsolve_tmp::rateType + linsolve::F + jac_config::JCType + grad_config::GCType + end + end + constcacheexpr,cacheexpr +end + +""" + gen_algcache(cacheexpr::Expr,constcachename::Symbol,algname::Symbol,tabname::Symbol) + +Generate expressions for `alg_cache(...)` emulating those in `caches/rosenbrock_caches.jl`. +""" +function gen_algcache(cacheexpr::Expr,constcachename::Symbol,algname::Symbol,tabname::Symbol) + @capture(cacheexpr, @cache mutable struct T_ fields__ end) || error("incorrect cache expression") + cachename = namify(T) + ksinit = Expr[] + valsyms = Symbol[] + for field in fields + if @capture(field, valsym_Symbol::valtype_) + push!(valsyms, valsym) + + if match(r"^k[1-9]+$", String(valsym)) !== nothing + push!(ksinit, :($valsym = zero(rate_prototype))) + end + end + end + + quote + function alg_cache(alg::$algname,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false}) + tf = TimeDerivativeWrapper(f,u,p) + uf = UDerivativeWrapper(f,t,p) + J,W = build_J_W(alg,u,uprev,p,t,dt,f,uEltypeNoUnits,Val(false)) + $constcachename(tf,uf,$tabname(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits)),J,W,nothing) + end + function alg_cache(alg::$algname,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true}) + du = zero(rate_prototype) + du1 = zero(rate_prototype) + du2 = zero(rate_prototype) + $(ksinit...) + fsalfirst = zero(rate_prototype) + fsallast = zero(rate_prototype) + dT = zero(rate_prototype) + J,W = build_J_W(alg,u,uprev,p,t,dt,f,uEltypeNoUnits,Val(true)) + tmp = zero(rate_prototype) + atmp = similar(u, uEltypeNoUnits) + weight = similar(u, uEltypeNoUnits) + tab = $tabname(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits)) + + tf = TimeGradientWrapper(f,uprev,p) + uf = UJacobianWrapper(f,t,p) + linsolve_tmp = zero(rate_prototype) + linprob = LinearProblem(W,_vec(linsolve_tmp); u0=_vec(tmp)) + linsolve = init(linprob,alg.linsolve,alias_A=true,alias_b=true, + Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), + Pr = Diagonal(_vec(weight))) + grad_config = build_grad_config(alg,f,tf,du1,t) + jac_config = build_jac_config(alg,f,uf,du1,uprev,u,tmp,du2) + $cachename($(valsyms...)) + end + end +end + +""" + gen_initialize(cachename::Symbol,constcachename::Symbol) + +Generate expressions for `initialize!(...)` in `perform_step/rosenbrock_perform_step.jl`. +It only generates a default version of `initialize!` which support 3rd-order Hermite interpolation. +""" +function gen_initialize(cachename::Symbol,constcachename::Symbol) + quote + function initialize!(integrator, cache::$constcachename) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + end + + function initialize!(integrator, cache::$cachename) + integrator.kshortsize = 2 + @unpack fsalfirst,fsallast = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = fsallast + resize!(integrator.k, integrator.kshortsize) + integrator.k .= [fsalfirst,fsallast] + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + end + end +end + +""" + gen_constant_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) + +Generate non-inplace version of `perform_step!` expression emulating those in `perform_step/rosenbrock_perform_step.jl`. +The `perform_step!` function calculates `k1,k2,k3,...` defined by `(-W)ki=f(u+aij*kj,t+ci*dt)+di*dt*dT+Cij*kj*dt, i=1,2,...,n_normalstep` +and then gives the result by `y_{n+1}=y_n+ki*bi`. Terms with 0s (according to tabmask) are skipped in the expressions. +Special steps can be added before calculating `y_{n+1}`. The non-inplace `perform_step!` assumes the mass_matrix==I. +""" +function gen_constant_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) + unpacktabexpr=:(@unpack ()=cache.tab) + unpacktabexpr.args[3].args[1].args=_nonzero_vals(tabmask) + dtCijexprs=[:($(Symbol(:dtC,Cind[1],Cind[2]))=$(Symbol(:C,Cind[1],Cind[2]))/dt) for Cind in findall(!iszero,tabmask.C)] + dtdiexprs=[:($(Symbol(:dtd,dind))=dt*$(Symbol(:d,dind))) for dind in eachindex(tabmask.d)] + iterexprs=[] + for i in 1:n_normalstep + aijkj=[:($(Symbol(:a,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.a[i+1,:])] + Cijkj=[:($(Symbol(:dtC,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.C[i+1,:])] + push!(iterexprs, + quote + $(Symbol(:k,i)) = _reshape(W\-_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u=+(uprev,$(aijkj...)) + du = f(u, p, t+$(Symbol(:c,i+1))*dt) + integrator.stats.nf += 1 + if mass_matrix === I + linsolve_tmp=+(du,$(Symbol(:dtd,i+1))*dT,$(Cijkj...)) + else + linsolve_tmp=du+$(Symbol(:dtd,i+1))*dT+mass_matrix*(+($(Cijkj...))) + end + end) + end + push!(iterexprs,specialstepexpr) + n=length(tabmask.b) + biki=[:($(Symbol(:b,i))*$(Symbol(:k,i))) for i in 1:n] + push!(iterexprs, + quote + $(Symbol(:k,n))=_reshape(W\-_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u=+(uprev,$(biki...)) + end) + + adaptiveexpr=[] + if typeof(tabmask)<:RosenbrockAdaptiveTableau + btildeiki=[:($(Symbol(:btilde,i))*$(Symbol(:k,i))) for i in findall(!iszero,tabmask.btilde)] + push!(adaptiveexpr,quote + if integrator.opts.adaptive + utilde = +($(btildeiki...)) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol,integrator.opts.internalnorm,t) + integrator.EEst = integrator.opts.internalnorm(atmp,t) + end + end) + end + quote + @muladd function perform_step!(integrator, cache::$cachename, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + @unpack tf,uf = cache + $unpacktabexpr + + $(dtCijexprs...) + $(dtdiexprs...) + dtgamma = dt*gamma + + mass_matrix = integrator.f.mass_matrix + + # Time derivative + tf.u = uprev + dT = ForwardDiff.derivative(tf, t) + + W = calc_W(integrator, cache, dtgamma, repeat_step, true) + linsolve_tmp = integrator.fsalfirst + dtd1*dT #calc_rosenbrock_differentiation! + + $(iterexprs...) + + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + + $(adaptiveexpr...) + end + end + +end + +""" + gen_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) + +Generate inplace version of `perform_step!` expression emulating those in `perform_step/rosenbrock_perform_step.jl`. +The inplace `perform_step!` produces the same result as the non-inplace version except that it treats the mass_matrix appropriately. +""" +function gen_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) + unpacktabexpr=:(@unpack ()=cache.tab) + unpacktabexpr.args[3].args[1].args=_nonzero_vals(tabmask) + dtCij=[:($(Symbol(:dtC,"$(Cind[1])$(Cind[2])"))=$(Symbol(:C,"$(Cind[1])$(Cind[2])"))/dt) for Cind in findall(!iszero,tabmask.C)] + dtdi=[:($(Symbol(:dtd,dind[1]))=dt*$(Symbol(:d,dind[1]))) for dind in eachindex(tabmask.d)] + iterexprs=[] + for i in 1:n_normalstep + ki=Symbol(:k,i) + dtdj=Symbol(:dtd,i+1) + aijkj=[:($(Symbol(:a,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.a[i+1,:])] + dtCijkj=[:($(Symbol(:dtC,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.C[i+1,:])] + repeatstepexpr=[] + if i==1 + repeatstepexpr=[:(!repeat_step)] + end + push!(iterexprs,quote + + if $(i==1) + # Must be a part of the first linsolve for preconditioner step + linres = dolinsolve(integrator, linsolve; A = !repeat_step ? W : nothing, b = _vec(linsolve_tmp)) + else + linres = dolinsolve(integrator, linsolve; b = _vec(linsolve_tmp)) + end + + linsolve = linres.cache + vecu = _vec(linres.u) + vecki = _vec($ki) + + @.. broadcast=false vecki = -vecu + + integrator.stats.nsolve += 1 + @.. broadcast=false u = +(uprev,$(aijkj...)) + f( du, u, p, t+$(Symbol(:c,i+1))*dt) + integrator.stats.nf += 1 + if mass_matrix === I + @.. broadcast=false linsolve_tmp = +(du,$dtdj*dT,$(dtCijkj...)) + else + @.. broadcast=false du1 = +($(dtCijkj...)) + mul!(_vec(du2),mass_matrix,_vec(du1)) + @.. broadcast=false linsolve_tmp = du + $dtdj*dT + du2 + end + end) + end + push!(iterexprs,specialstepexpr) + n=length(tabmask.b) + ks=[Symbol(:k,i) for i in 1:n] + klast=Symbol(:k,n) + biki=[:($(Symbol(:b,i))*$(Symbol(:k,i))) for i in 1:n] + push!(iterexprs,quote + + linres = dolinsolve(integrator, linsolve; b = _vec(linsolve_tmp)) + linsolve = linres.cache + vecu = _vec(linres.u) + vecklast = _vec($klast) + @.. broadcast=false vecklast = -vecu + + integrator.stats.nsolve += 1 + @.. broadcast=false u = +(uprev,$(biki...)) + end) + + adaptiveexpr=[] + if typeof(tabmask)<:RosenbrockAdaptiveTableau + btildeiki=[:($(Symbol(:btilde,i))*$(Symbol(:k,i))) for i in findall(!iszero,tabmask.btilde)] + push!(adaptiveexpr,quote + utilde=du + if integrator.opts.adaptive + @.. broadcast=false utilde = +($(btildeiki...)) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol,integrator.opts.internalnorm,t) + integrator.EEst = integrator.opts.internalnorm(atmp,t) + end + end) + end + quote + @muladd function perform_step!(integrator, cache::$cachename, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + @unpack du,du1,du2,fsallast,dT,J,W,uf,tf,$(ks...),linsolve_tmp,jac_config,atmp,weight = cache + $unpacktabexpr + + # Assignments + sizeu = size(u) + uidx = eachindex(integrator.uprev) + mass_matrix = integrator.f.mass_matrix + + # Precalculations + $(dtCij...) + $(dtdi...) + dtgamma = dt*gamma + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) + + calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) + + linsolve = cache.linsolve + + $(iterexprs...) + + f( fsallast, u, p, t + dt) + integrator.stats.nf += 1 + + $(adaptiveexpr...) + end + end +end + +""" + RosenbrockW6S4OSTableau() + +Rahunanthan, A., & Stanescu, D. (2010). High-order W-methods. +Journal of computational and applied mathematics, 233(8), 1798-1811. +""" +function RosenbrockW6S4OSTableau() + a=[0 0 0 0 0; + 0.5812383407115008 0 0 0 0; + 0.9039624413714670 1.8615191555345010 0 0 0; + 2.0765797196750000 0.1884255381414796 1.8701589674910320 0 0; + 4.4355506384843120 5.4571817986101890 4.6163507880689300 3.1181119524023610 0; + 10.791701698483260 -10.05691522584131 14.995644854284190 5.2743399543909430 1.4297308712611900] + C=[0 0 0 0 0; + -2.661294105131369 0 0 0 0; + -3.128450202373838 0.0000000000000000 0 0 0; + -6.920335474535658 -1.202675288266817 -9.733561811413620 0 0; + -28.09530629102695 20.371262954793770 -41.04375275302869 -19.66373175620895 0; + 9.7998186780974000 11.935792886603180 3.6738749290132010 14.807828541095500 0.8318583998690680] + b=[6.4562170746532350,-4.853141317768053,9.7653183340692600,2.0810841772787230,0.6603936866352417,0.6000000000000000] + gamma=0.2500000000000000 + d=[0.2500000000000000,0.0836691184292894,0.0544718623516351,-0.3402289722355864,0.0337651588339529,-0.0903074267618540] + c=[0 ,0.1453095851778752,0.3817422770256738,0.6367813704374599,0.7560744496323561,0.9271047239875670] + RosenbrockFixedTableau(a,C,b,gamma,d,c) +end + +""" + @RosenbrockW6S4OS(part) + +Generate code for the RosenbrockW6S4OS method. +`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. +`@RosenbrockW6S4OS(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. +`@RosenbrockW6S4OS(:cache)` should be placed in `caches/rosenbrock_caches.jl`. +`@RosenbrockW6S4OS(:init)` and `@RosenbrockW6S4OS(:performstep)` should be +placed in `perform_step/rosenbrock_perform_step.jl`. +""" +macro RosenbrockW6S4OS(part) + tab=RosenbrockW6S4OSTableau() + tabmask=_masktab(tab) + algname=:RosenbrockW6S4OS + tabname=:RosenbrockW6S4OSTableau + tabstructname=:RosenbrockW6STableau + cachename=:RosenbrockW6SCache + constcachename=:RosenbrockW6SConstantCache + n_normalstep=length(tab.b)-1 + if part.value==:tableau + #println("Generating const cache") + tabstructexpr=gen_tableau_struct(tabmask,tabstructname) + tabexpr=gen_tableau(tab,tabstructexpr,tabname) + return esc(quote $([tabstructexpr,tabexpr]...) end) + elseif part.value==:cache + #println("Generating cache") + constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) + algcacheexpr=gen_algcache(cacheexpr,constcachename,algname,tabname) + return esc(quote $([constcacheexpr,cacheexpr,algcacheexpr]...) end) + elseif part.value==:init + #println("Generating initialize") + return esc(gen_initialize(cachename,constcachename)) + elseif part.value==:performstep + #println("Generating perform_step") + constperformstepexpr=gen_constant_perform_step(tabmask,constcachename,n_normalstep) + performstepexpr=gen_perform_step(tabmask,cachename,n_normalstep) + return esc(quote $([constperformstepexpr,performstepexpr]...) end) + else + throw(ArgumentError("Unknown parameter!")) + nothing + end +end + +""" + Ros4dummyTableau() + +Generate a dummy tableau for ROS4 methods. It can be considered as performing elementwise OR to the masks +of those specific tableaus: `Ros4dummyTableau()==_masktab(RosShamp4Tableau()) OR _masktab(Veldd4Tableau()) OR ...` +ROS4 methods have the property of a4j==a3j so a is a 3*3 matrix instead of a 4*4 matrix and c is a 1*3 vector instead of a 1*4 vector. +""" +function Ros4dummyTableau()#create a tabmask for all ROS4 methods where false->0,true->non-0 + a=[false false false; + true false false; + true true false] + C=[false false false false; + true false false false; + true true false false; + true true true false] + b=[true,true,true,true] + btilde=[true,true,true,true] + gamma=true + c=[false,true,true] + d=[true,true,true,true] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + RosShamp4Tableau() + +L. F. Shampine, Implementation of Rosenbrock Methods, +ACM Transactions on Mathematical Software (TOMS), 8: 2, 93-113. +doi:10.1145/355993.355994 +""" +function RosShamp4Tableau() + a=[0 0 0; + 2 0 0; + 48//25 6//25 0] + C=[ 0 0 0 0; + -8 0 0 0; + 372//25 12//5 0 0; + -112//125 -54//125 -2//5 0] + b=[19//9,1//2,25//108,125//108] + btilde=[17//54,7//36,0,125//108] + gamma=1//2 + c=[0,1,3//5] + d=[1//2,-3//2,242//100,116//1000]#2.42,0.116 + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + Veldd4Tableau() + +van Veldhuizen, D-stability and Kaps-Rentrop-methods, +M. Computing (1984) 32: 229. doi:10.1007/BF02243574 +""" +function Veldd4Tableau() + a=[0 0 0; + 2 0 0; + 4.812234362695436 4.578146956747842 0] + C=[ 0 0 0 0; + -5.333333333333331 0 0 0; + 6.100529678848254 1.804736797378427 0 0; + -2.540515456634749 -9.443746328915205 -1.988471753215993 0] + b=[4.289339254654537,5.036098482851414,0.6085736420673917,1.355958941201148] + btilde=[2.175672787531755,2.950911222575741,-0.7859744544887430,-1.355958941201148] + gamma=0.2257081148225682 + c=[0,0.4514162296451364,0.8755928946018455] + d=[0.2257081148225682,-0.04599403502680582,0.5177590504944076,-0.03805623938054428] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + Velds4Tableau() + +van Veldhuizen, D-stability and Kaps-Rentrop-methods, +M. Computing (1984) 32: 229. doi:10.1007/BF02243574 +""" +function Velds4Tableau() + a=[0 0 0; + 2 0 0; + 7//4 1//4 0] + C=[ 0 0 0 0; + -8 0 0 0; + -8 -1 0 0; + 1//2 -1//2 2 0] + b=[4//3,2//3,-4//3,4//3] + btilde=[-1//3,-1//3,0,-4//3] + gamma=1//2 + c=[0,1,1//2] + d=[1//2,-3//2,-3//4,1//4] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + GRK4TTableau() + +Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four +with stepsize control for stiff ordinary differential equations. +P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 +""" +function GRK4TTableau() + a=[0 0 0; + 2 0 0; + 4.524708207373116 4.163528788597648 0] + C=[ 0 0 0 0; + -5.071675338776316 0 0 0; + 6.020152728650786 0.1597506846727117 0 0; + -1.856343618686113 -8.505380858179826 -2.084075136023187 0] + b=[3.957503746640777,4.624892388363313,0.6174772638750108,1.282612945269037] + btilde=[2.302155402932996,3.073634485392623,-0.8732808018045032,-1.282612945269037] + gamma=0.231 + c=[0,0.462,0.8802083333333334] + d=[0.2310000000000000,-0.03962966775244303,0.5507789395789127,-0.05535098457052764] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + GRK4ATableau() + +Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four +with stepsize control for stiff ordinary differential equations. +P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 +""" +function GRK4ATableau() + a=[0 0 0; + 1.108860759493671 0 0; + 2.377085261983360 0.1850114988899692 0] + C=[ 0 0 0 0; + -4.920188402397641 0 0 0; + 1.055588686048583 3.351817267668938 0 0; + 3.846869007049313 3.427109241268180 -2.162408848753263 0] + b=[1.845683240405840,0.1369796894360503,0.7129097783291559,0.6329113924050632] + btilde=[0.04831870177201765,-0.6471108651049505,0.2186876660500240,-0.6329113924050632] + gamma=0.395 + c=[0,0.438,0.87] + d=[0.395,-0.3726723954840920,0.06629196544571492,0.4340946962568634] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + Ros4LSTableau() + +E. Hairer, G. Wanner, Solving ordinary differential equations II, +stiff and differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) +""" +function Ros4LSTableau() + a=[0 0 0; + 2 0 0; + 1.867943637803922 0.2344449711399156 0] + C=[ 0 0 0 0; + -7.137615036412310 0 0 0; + 2.580708087951457 0.6515950076447975 0 0; + -2.137148994382534 -0.3214669691237626 -0.6949742501781779 0] + b=[2.255570073418735,0.2870493262186792,0.4353179431840180,1.093502252409163] + btilde=[-0.2815431932141155,-0.07276199124938920,-0.1082196201495311,-1.093502252409163] + gamma=0.5728200000000000 + c=[0,1.145640000000000,0.6552168638155900] + d=[0.5728200000000000,-1.769193891319233,0.7592633437920482,-0.1049021087100450] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + @Rosenbrock4(part) + +Generate code for the Rosenbrock4 methods: RosShamp4, Veldd4, Velds4, GRK4A, GRK4T, Ros4LStab. +`part` should be one of `:tableau`, `:cache`, `:performstep`. +`@Rosenbrock4(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. +`@Rosenbrock4(:cache)` should be placed in `caches/rosenbrock_caches.jl`. +`@Rosenbrock4(:performstep)` should be placed in `perform_step/rosenbrock_perform_step.jl`. +The `initialize!` function for Rosenbrock4 methods is already included in `rosenbrock_perform_step.jl`. +The special property of ROS4 methods that a4j==a3j requires a special step in `perform_step!` that +calculates `linsolve_tmp` from the previous `du` which reduces a function call. +""" +macro Rosenbrock4(part) + tabmask=Ros4dummyTableau()#_masktab(tab) + cachename=:Rosenbrock4Cache + constcachename=:Rosenbrock4ConstantCache + RosShamp4tabname=:RosShamp4Tableau + Veldd4tabname=:Veldd4Tableau + Velds4tabname=:Velds4Tableau + GRK4Ttabname=:GRK4TTableau + GRK4Atabname=:GRK4ATableau + Ros4LStabname=:Ros4LStabTableau + n_normalstep=2 #for the third step a4j=a3j which reduced one function call + if part.value==:tableau + #println("Generating tableau for Rosenbrock4") + tabstructexpr=gen_tableau_struct(tabmask,:Ros4Tableau) + tabexprs=Array{Expr,1}() + push!(tabexprs,tabstructexpr) + push!(tabexprs,gen_tableau(RosShamp4Tableau(),tabstructexpr,RosShamp4tabname)) + push!(tabexprs,gen_tableau(Veldd4Tableau(),tabstructexpr,Veldd4tabname)) + push!(tabexprs,gen_tableau(Velds4Tableau(),tabstructexpr,Velds4tabname)) + push!(tabexprs,gen_tableau(GRK4TTableau(),tabstructexpr,GRK4Ttabname)) + push!(tabexprs,gen_tableau(GRK4ATableau(),tabstructexpr,GRK4Atabname)) + push!(tabexprs,gen_tableau(Ros4LSTableau(),tabstructexpr,Ros4LStabname)) + return esc(quote $(tabexprs...) end) + elseif part.value==:cache + #println("Generating cache for Rosenbrock4") + constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) + cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:RosShamp4,RosShamp4tabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Veldd4,Veldd4tabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Velds4,Velds4tabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:GRK4T,GRK4Ttabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:GRK4A,GRK4Atabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Ros4LStab,Ros4LStabname)) + return esc(quote $(cacheexprs...) end) + elseif part.value==:performstep + #println("Generating perform_step for Rosenbrock4") + specialstepconst=quote + k3 = _reshape(W\-_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + #u = uprev + a31*k1 + a32*k2 #a4j=a3j + #du = f(u, p, t+c3*dt) #reduced function call + if mass_matrix === I + linsolve_tmp = du + dtd4*dT + dtC41*k1 + dtC42*k2 + dtC43*k3 + else + linsolve_tmp = du + dtd4*dT + mass_matrix * (dtC41*k1 + dtC42*k2 + dtC43*k3) + end + end + specialstep=quote + + linres = dolinsolve(integrator, linsolve; b = _vec(linsolve_tmp)) + linsolve = linres.cache + cache.linsolve = linsolve + vecu = _vec(linres.u) + veck3 = _vec(k3) + @.. broadcast=false veck3 = -vecu + + integrator.stats.nsolve += 1 + #@.. broadcast=false u = uprev + a31*k1 + a32*k2 #a4j=a3j + #f( du, u, p, t+c3*dt) #reduced function call + if mass_matrix === I + @.. broadcast=false linsolve_tmp = du + dtd4*dT + dtC41*k1 + dtC42*k2 + dtC43*k3 + else + @.. broadcast=false du1 = dtC41*k1 + dtC42*k2 + dtC43*k3 + mul!(du2,mass_matrix,du1) + @.. broadcast=false linsolve_tmp = du + dtd4*dT + du2 + end + end + constperformstepexpr=gen_constant_perform_step(tabmask,constcachename,n_normalstep,specialstepconst) + performstepexpr=gen_perform_step(tabmask,cachename,n_normalstep,specialstep) + return esc(quote $([constperformstepexpr,performstepexpr]...) end) + else + throw(ArgumentError("Unknown parameter!")) + nothing + end +end + +#ROS2, ROS23 and ROS34PW methods (Rang and Angermann, 2005) + +""" + Ros34dummyTableau() + +Generate a dummy tableau for ROS34W methods proposed by Rang and Angermann. This type of methods has 4 steps. +""" +function Ros34dummyTableau() + a=[false false false false; + true false false false; + true true false false; + true true true false] + C=[false false false false; + true false false false; + true true false false; + true true true false] + b=[true,true,true,true] + btilde=[true,true,true,true] + gamma=true + c=[false,true,true,true] + d=[true,true,true,true] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + Ros23dummyTableau() + +Generate a dummy tableau for ROS23 methods proposed by Rang. This type of methods has 3 steps. +""" +function Ros23dummyTableau() + a=[false false false; + true false false; + true true false] + C=[false false false; + true false false; + true true false;] + b=[true,true,true] + btilde=[true,true,true] + gamma=true + c=[false,true,true] + d=[true,true,true] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + Ros2dummyTableau() + +Generate a dummy tableau for ROS2 methods. This type of methods has 2 steps. +""" +function Ros2dummyTableau() + a=[false false; + true false] + C=[false false; + true false] + b=[true,true] + btilde=[true,true] + gamma=true + c=[false,true] + d=[true,true] + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + + +""" + _transformtab(Alpha,Gamma,B,Bhat) + +Transform the tableau from values in the paper into values used in OrdinaryDiffEq according to p112 in Hairer and Wanner. + +E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and +differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) +""" +function _transformtab(Alpha,Gamma,B,Bhat) + invGamma=inv(Gamma) + a=Alpha*invGamma + C=diagm(0=>diag(invGamma))-invGamma + b=[(transpose(B)*invGamma)...]# [2Darray...]=>1Darray + btilde=[(transpose(B-Bhat)*invGamma)...] + gamma=Gamma[1,1]#Gamma11==Gamma22==...==Gammass + d=[sum(Gamma,dims=2)...]#di=sum_j Gamma_ij + c=[sum(Alpha,dims=2)...]#ci=sum_j Alpha_ij + (a,C,b,btilde,d,c) +end + + + + +# 2 step ROS Methods +""" + ROS2Tableau() +2nd order stiffly accurate Rosenbrock method with 2 internal stages with (Rinf=0). +The embedded method is taken from Kinetic PreProcessor (KPP). +J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems +https://doi.org/10.1137/S1064827597326651 +""" +function ROS2Tableau() # 2nd order + gamma=1.7071067811865475 # 1+1/sqrt(2) + Alpha=[0 0; + 1. 0] + Gamma=[gamma 0; + -3.414213562373095 gamma] + B=[0.5, 0.5] + Bhat=[1, 0] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_wanner_docstring( +""" +An Order 2/3 L-Stable Rosenbrock-W method which is good for very stiff equations with oscillations at low tolerances. 2nd order stiff-aware interpolation. +""", +"Rosenbrock23", +references = """ +- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of +Scientific Computing, 18 (1), pp. 1-22. +""", +with_step_limiter = true) Rosenbrock23 + +@doc rosenbrock_wanner_docstring( +""" +An Order 3/2 A-Stable Rosenbrock-W method which is good for mildly stiff equations without oscillations at low tolerances. Note that this method is prone to instability in the presence of oscillations, so use with caution. 2nd order stiff-aware interpolation. +""", +"Rosenbrock32", +references = """ +- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of +Scientific Computing, 18 (1), pp. 1-22. +""", +with_step_limiter = true) Rosenbrock32 + +@doc rosenbrock_docstring( +""" +3rd order A-stable and stiffly stable Rosenbrock method. Keeps high accuracy on discretizations of nonlinear parabolic PDEs. +""", +"ROS3P", +references = """ +- Lang, J. & Verwer, ROS3P—An Accurate Third-Order Rosenbrock Solver Designed for + Parabolic Problems J. BIT Numerical Mathematics (2001) 41: 731. doi:10.1023/A:1021900219772 +""", +with_step_limiter = true) ROS3P + +@doc rosenbrock_wanner_docstring( +""" +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. +""", +"Rodas23W", +references = """ +- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate for dense output and Julia implementation, + In progress. +""", +with_step_limiter = true) Rodas23W + +@doc rosenbrock_wanner_docstring( +""" +A 4th order L-stable Rosenbrock-W method. +""", +"ROS34PW1a") ROS34PW1a + +@doc rosenbrock_wanner_docstring( +""" +A 4th order L-stable Rosenbrock-W method. +""", +"ROS34PW1b") ROS34PW1b + +@doc rosenbrock_wanner_docstring( +""" +A 4th order stiffy accurate Rosenbrock-W method for PDAEs. +""", +"ROS34PW2") ROS34PW2 + +@doc rosenbrock_wanner_docstring( +""" +A 4th order strongly A-stable (Rinf~0.63) Rosenbrock-W method. +""", +"ROS34PW3") ROS34PW3 + +@doc rosenbrock_docstring( +""" +An A-stable 4th order Rosenbrock method. +""", +"RosShamp4", +references = """ +- L. F. Shampine, Implementation of Rosenbrock Methods, ACM Transactions on + Mathematical Software (TOMS), 8: 2, 93-113. doi:10.1145/355993.355994 +""") RosShamp4 + +@doc rosenbrock_docstring( +""" +3rd order A-stable and stiffly stable Rosenbrock method. +""", +"Rodas3", +references = """ +- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks + within the Julia Differential Equations package. + In: BIT Numerical Mathematics, 63(2), 2023 +""", +with_step_limiter=true) Rodas3 + +@doc rosenbrock_docstring( +""" +3rd order A-stable and stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant +and additional error test for interpolation. Keeps accuracy on discretizations of linear parabolic PDEs. +""", +"Rodas3P", +references = """ +- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate + for dense output and Julia implementation, + In progress. +""", +with_step_limiter=true) Rodas3P + +@doc rosenbrock_docstring( +""" +A 4th order L-stable Rosenbrock method. +""", +"Rodas4", +references = """ +- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and + differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) +""", +with_step_limiter=true) Rodas4 + +@doc rosenbrock_docstring( +""" +A 4th order A-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant +""", +"Ros4LStab", +references = """ +- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and + differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) +""", +with_step_limiter=true) Ros4LStab + + +@doc rosenbrock_docstring( +""" +A 4th order A-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant +""", +"Rodas42", +references = """ +- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and + differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) +""", +with_step_limiter=true) Rodas42 + +@doc rosenbrock_wanner_docstring( +""" +4th order A-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant. 4th order +on linear parabolic problems and 3rd order accurate on nonlinear parabolic problems (as opposed to +lower if not corrected). +""", +"Rodas4P", +references = """ +- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate + for dense output and Julia implementation, + In progress. +""", +with_step_limiter=true) Rodas4P + +@doc rosenbrock_wanner_docstring( +""" +A 4th order L-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant. 4th order +on linear parabolic problems and 3rd order accurate on nonlinear parabolic problems. It is an improvement +of Roadas4P and in case of inexact Jacobians a second order W method. +""", +"Rodas4P2", +references = """ +- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate + for dense output and Julia implementation, + In progress. +""", +with_step_limiter=true) Rodas4P2 + +@doc rosenbrock_docstring( +""" +A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. +""", +"Rodas5", +references = """ +- Di Marzo G. RODAS5(4) – Méthodes de Rosenbrock d’ordre 5(4) adaptées aux problemes + différentiels-algébriques. MSc mathematics thesis, Faculty of Science, + University of Geneva, Switzerland. +""", +with_step_limiter=true) Rodas5 + +@doc rosenbrock_docstring( +""" +A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. +Has improved stability in the adaptive time stepping embedding. +""", +"Rodas5P", +references = """ +- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks + within the Julia Differential Equations package. + In: BIT Numerical Mathematics, 63(2), 2023 +""", +with_step_limiter=true) Rodas5P + +@doc rosenbrock_docstring( +""" +A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. +Has improved stability in the adaptive time stepping embedding. +""", +"Rodas5Pr", +references = """ +- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - + Preprint 2024 + https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf +""", +with_step_limiter=true) Rodas5Pr + +@doc rosenbrock_docstring( +""" +A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. +Has improved stability in the adaptive time stepping embedding. +""", +"Rodas5Pe", +references = """ +- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - + Preprint 2024 + https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf +""", +with_step_limiter=true) Rodas5Pe + +@doc rosenbrock_docstring( +""" +An efficient 4th order Rosenbrock method. +""", +"GRK4T", +references = """ +- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control + for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 +""", +with_step_limiter=true) GRK4T + +@doc rosenbrock_docstring( +""" +An A-stable 4th order Rosenbrock method. Essentially "anti-L-stable" but efficient. +""", +"GRK4A", +references = """ +- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control + for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 +""", +with_step_limiter=true) GRK4A + +@doc rosenbrock_docstring( +""" +A 4th order D-stable Rosenbrock method. +""", +"Veldd4", +references = """ +- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. + doi:10.1007/BF02243574 +""", +with_step_limiter=true) Veldd4 + +@doc rosenbrock_docstring( +""" +A 4th order A-stable Rosenbrock method. +""", +"Velds4", +references = """ +- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. + doi:10.1007/BF02243574 +""", +with_step_limiter=true) Velds4 + +""" + @ROS2(part) + +Generate code for the 2 step ROS methods: ROS2 +`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. +`@ROS2(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. +`@ROS2(:cache)` should be placed in `caches/rosenbrock_caches.jl`. +`@ROS2(:init)` and `@ROS2(:performstep)` should be placed in +`perform_step/rosenbrock_perform_step.jl`. +""" +macro ROS2(part) + tabmask=Ros2dummyTableau() + cachename=:ROS2Cache + constcachename=:ROS2ConstantCache + ROS2tabname=:ROS2Tableau + n_normalstep=length(tabmask.b)-1 + if part.value==:tableau + tabstructexpr=gen_tableau_struct(tabmask,:Ros2Tableau) + tabexprs=Array{Expr,1}([tabstructexpr]) + push!(tabexprs,gen_tableau(ROS2Tableau(),tabstructexpr,ROS2tabname)) + return esc(quote $(tabexprs...) end) + elseif part.value==:cache + constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) + cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS2,ROS2tabname)) + return esc(quote $(cacheexprs...) end) + elseif part.value==:init + return esc(gen_initialize(cachename,constcachename)) + elseif part.value==:performstep + performstepexprs=Array{Expr,1}() + push!(performstepexprs,gen_constant_perform_step(tabmask,constcachename,n_normalstep)) + push!(performstepexprs,gen_perform_step(tabmask,cachename,n_normalstep)) + return esc(quote $(performstepexprs...) end) + else + throw(ArgumentError("Unknown parameter!")) + nothing + end +end + +@doc rosenbrock_docstring( +""" +A 2nd order L-stable Rosenbrock method with 2 internal stages. +""", +"ROS2", +references = """ +- J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems + https://doi.org/10.1137/S1064827597326651 +""") ROS2 + +# 3 step ROS Methods +""" + ROS2PRTableau() + +2nd order stiffly accurate Rosenbrock method with 3 internal stages with (Rinf=0). +For problems with medium stiffness the convergence behaviour is very poor and it is recommended to use +[`ROS2S`](@ref) instead. + +Rang, Joachim (2014): The Prothero and Robinson example: +Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 +""" +function ROS2PRTableau() # 2nd order + gamma=2.28155493653962e-01 + Alpha=[0 0 0; + 1.00000000000000e+00 0 0; + 0.00000000000000e+00 1.0000000000000e+00 0] + Gamma=[gamma 0 0; + -2.28155493653962e-01 gamma 0; + 6.47798871261042e-01 -8.75954364915004e-01 gamma] + B=[6.47798871261042e-01,1.24045635084996e-01, 2.28155493653962e-01] + Bhat=[7.71844506346038e-01, 2.28155493653962e-01, 0.00000000000000e+00] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_docstring( +""" +2nd order stiffly accurate Rosenbrock method with 3 internal stages with (Rinf=0). +For problems with medium stiffness the convergence behaviour is very poor and it is recommended to use +[`ROS2S`](@ref) instead. +""", +"ROS2PR", +references = """ +- Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 +""") +ROS2PR + + + +""" + ROS2STableau() + +2nd order stiffly accurate Rosenbrock-Wanner W-method with 3 internal stages with B_PR consistent of order 2 with (Rinf=0). +More Information at https://doi.org/10.24355/dbbs.084-201408121139-0 + +Rang, Joachim (2014): The Prothero and Robinson example: +Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 +""" +function ROS2STableau() # 2nd order + gamma=2.92893218813452e-01 + Alpha=[0 0 0; + 5.85786437626905e-01 0 0; + 0.00000000000000e+00 1.0000000000000e+00 0] + Gamma=[gamma 0 0; + -5.85786437626905e-01 gamma 0; + 3.53553390593274e-01 -6.46446609406726e-01 gamma] + B=[3.53553390593274e-01,3.53553390593274e-01, 2.92893218813452e-01] + Bhat=[3.33333333333333e-01, 3.33333333333333e-01, 3.33333333333333e-01] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_wanner_docstring( +""" +2nd order stiffly accurate Rosenbrock-Wanner W-method with 3 internal stages with B_PR consistent of order 2 with (Rinf=0). +""", +"ROS2S", +references = """ +- Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 +""") +ROS2S + + +""" + ROS3Tableau() +E. Hairer, G. Wanner, Solving ordinary differential equations II, +stiff and differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) +With coefficients from https://doi.org/10.1016/S1352-2310(97)83212-8 + +""" +function ROS3Tableau() # 3rd order + gamma=0.435866521508459 + Alpha=[0 0 0; + 0.435866521508459 0 0; + 0.435866521508459 0 0] + Gamma=[gamma 0 0; + -0.19294655696029095 gamma 0; + 0 1.7492714812579468 gamma] + B=[-0.7545741238540432,1.9410040706196443, -0.18642994676560104] + Bhat=[-1.5335874578414959, 2.817451311486258, -0.28386385364476185] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_docstring( +""" +3rd order L-stable Rosenbrock method with 3 internal stages with an embedded strongly +A-stable 2nd order method. +""", +"ROS3", +references = """ +- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and + differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) +""") ROS3 + + +""" + ROS3PRTableau() + +3nd order stiffly accurate Rosenbrock-Wanner method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73. + +Rang, Joachim (2014): The Prothero and Robinson example: +Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 +""" +function ROS3PRTableau() # 3rd order + gamma=7.88675134594813e-01 + Alpha=[0 0 0; + 2.36602540378444e+00 0 0; + 0.00000000000000e+00 1.0000000000000e+00 0] + Gamma=[gamma 0 0; + -2.36602540378444e+00 gamma 0; + -2.84686425165674e-01 -1.08133897861876e+00 gamma] + B=[2.92663844023951e-01,-8.13389786187641e-02, 7.88675134594813e-01] + Bhat=[1.11324865405187e-01, 1.00000000000000e-01, 7.88675134594813e-01] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_docstring( +""" +3nd order stiffly accurate Rosenbrock method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73. +""", +"ROS3PR", +references = """ +- Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 +""") ROS3PR + + + +""" + Scholz4_7Tableau() + +3nd order stiffly accurate Rosenbrock method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73 +Convergence with order 4 for the stiff case, but has a poor accuracy. + +Rang, Joachim (2014): The Prothero and Robinson example: +Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 +""" +function Scholz4_7Tableau() # 3rd order + gamma=7.88675134594813e-01 + Alpha=[0 0 0; + 2.36602540378444e+00 0 0; + 2.50000000000000e-01 1.0000000000000e+00 0] + Gamma=[gamma 0 0; + -2.36602540378444e+00 gamma 0; + -6.13414364537605e-01 -1.10383267558217e+00 gamma] + B=[4.95076910424059e-01,-1.12898126628685e-01, 6.17821216204626e-01] + Bhat=[3.33333333333333e-01, 3.33333333333333e-01, 3.33333333333333e-01] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_docstring( +""" +3nd order stiffly accurate Rosenbrock method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73. +Convergence with order 4 for the stiff case, but has a poor accuracy. +""", +"Scholz4_7", +references = """ +- Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 +""") Scholz4_7 + + +""" + @ROS23(part) + +Generate code for the 3 step ROS methods: ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 +`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. +`@ROS23(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. +`@ROS23(:cache)` should be placed in `caches/rosenbrock_caches.jl`. +`@ROS23(:init)` and `@ROS23(:performstep)` should be placed in +`perform_step/rosenbrock_perform_step.jl`. +""" +macro ROS23(part) + tabmask=Ros23dummyTableau() + cachename=:ROS23Cache + constcachename=:ROS23ConstantCache + ROS2PRtabname=:ROS2PRTableau + ROS2Stabname=:ROS2STableau + ROS3tabname=:ROS3Tableau + ROS3PRtabname=:ROS3PRTableau + Scholz4_7tabname=:Scholz4_7Tableau + n_normalstep=length(tabmask.b)-1 + if part.value==:tableau + tabstructexpr=gen_tableau_struct(tabmask,:Ros23Tableau) + tabexprs=Array{Expr,1}([tabstructexpr]) + push!(tabexprs,gen_tableau(ROS2PRTableau(),tabstructexpr,ROS2PRtabname)) + push!(tabexprs,gen_tableau(ROS2STableau(),tabstructexpr,ROS2Stabname)) + push!(tabexprs,gen_tableau(ROS3Tableau(),tabstructexpr,ROS3tabname)) + push!(tabexprs,gen_tableau(ROS3PRTableau(),tabstructexpr,ROS3PRtabname)) + push!(tabexprs,gen_tableau(Scholz4_7Tableau(),tabstructexpr,Scholz4_7tabname)) + return esc(quote $(tabexprs...) end) + elseif part.value==:cache + constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) + cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS2PR,ROS2PRtabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS2S,ROS2Stabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3,ROS3tabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3PR,ROS3PRtabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Scholz4_7,Scholz4_7tabname)) + return esc(quote $(cacheexprs...) end) + elseif part.value==:init + return esc(gen_initialize(cachename,constcachename)) + elseif part.value==:performstep + performstepexprs=Array{Expr,1}() + push!(performstepexprs,gen_constant_perform_step(tabmask,constcachename,n_normalstep)) + push!(performstepexprs,gen_perform_step(tabmask,cachename,n_normalstep)) + return esc(quote $(performstepexprs...) end) + else + throw(ArgumentError("Unknown parameter!")) + nothing + end +end + + + + +# 4 step ROS Methods +""" + ROS34PW1aTableau() + +L-Stable, Rosenbrock-W method with order 3 and 4 inner steps + +Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial +differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. +""" +function ROS34PW1aTableau() + gamma=4.358665215084590e-1 + Alpha=[0 0 0 0; + 2.218787467653286 0 0 0; + 0 0 0 0; # can reduce one function call with specialized perform_step + 1.208587690772214 7.511610241919324e-2 0.5 0] + Gamma=[ gamma 0 0 0; + -2.218787467653286 gamma 0 0; + -9.461966143940745e-2 -7.913526735718213e-3 gamma 0; + -1.870323744195384 -9.624340112825115e-2 2.726301276675511e-1 gamma] + B=[3.285609536316354e-1,-5.785609536316354e-1,0.25,1] + Bhat=[-0.25,0,0.25,1]#B-Bhat[3:4]==[0,0] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + ROS34PW1bTableau() + +L-Stable, Rosenbrock-W method with order 3 and 4 inner steps + +Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial +differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. +""" +function ROS34PW1bTableau() + gamma=4.358665215084590e-1 + Alpha=[0 0 0 0; + 2.218787467653286 0 0 0; + 2.218787467653286 0 0 0; # can reduce one function call with specialized perform_step + 1.453923375357884 0 0.1 0] + Gamma=[ gamma 0 0 0; + -2.218787467653286 gamma 0 0; + -2.848610224639349 -5.267530183845237e-2 gamma 0; + -1.128167857898393 -1.677546870499461e-1 5.452602553351021e-2 gamma] + B=[5.495647928937977e-1,-5.507258170857301e-1,0.25,7.511610241919324e-1] + Bhat=[-1.161024191932427e-3,0,0.25,7.511610241919324e-1]#B-Bhat[3:4]==[0,0] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + ROS34PW2Tableau() + +A stiffy accurate Rosenbrock-W method with order 3 and 4 inner steps whose +embedded method is strongly A-stable with Rinf~=0.48 + +Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial +differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. +""" +function ROS34PW2Tableau() + gamma=4.3586652150845900e-1 + Alpha=[0 0 0 0; + 8.7173304301691801e-1 0 0 0; + 8.4457060015369423e-1 -1.1299064236484185e-1 0 0; + 0 0 1 0] + Gamma=[ gamma 0 0 0; + -8.7173304301691801e-1 gamma 0 0; + -9.0338057013044082e-1 5.4180672388095326e-2 gamma 0; + 2.4212380706095346e-1 -1.2232505839045147 5.4526025533510214e-1 gamma] + B=[2.4212380706095346e-1,-1.2232505839045147,1.5452602553351020,4.3586652150845900e-1] + Bhat=[3.7810903145819369e-1,-9.6042292212423178e-2,0.5,2.1793326075422950e-1] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + ROS34PW3Tableau() + +an A-stable (Rinf~=0.63), Rosenbrock-W method with order 4 and 4 inner steps. + +Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial +differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. +""" +function ROS34PW3Tableau()#4th order + gamma=1.0685790213016289 + Alpha=[0 0 0 0; + 2.5155456020628817 0 0 0; + 5.0777280103144085e-1 0.75 0 0; + 1.3959081404277204e-1 -3.3111001065419338e-1 8.2040559712714178e-1 0] + Gamma=[ gamma 0 0 0; + -2.5155456020628817 gamma 0 0; + -8.7991339217106512e-1 -9.6014187766190695e-1 gamma 0; + -4.1731389379448741e-1 4.1091047035857703e-1 -1.3558873204765276 gamma] + B=[2.2047681286931747e-1,2.7828278331185935e-3,7.1844787635140066e-3,7.6955588053404989e-1] + Bhat=[3.1300297285209688e-1,-2.8946895245112692e-1,9.7646597959903003e-1,0] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +""" + ROS34PRwTableau() + +3rd order stiffly accurate Rosenbrock-Wanner W-method with 4 internal stages, +B_PR consistent of order 2. +The order of convergence decreases if medium stiff problems are considered. + +Joachim Rang, Improved traditional Rosenbrock-Wanner methods for stiff ODEs and DAEs, +Journal of Computational and Applied Mathematics: https://doi.org/10.1016/j.cam.2015.03.010 +""" +function ROS34PRwTableau() # 3rd order + gamma=4.3586652150845900e-01 + Alpha=[0 0 0 0; + 8.7173304301691801e-01 0 0 0; + 1.4722022879435914e+00 -3.1840250568090289e-01 0 0; + 8.1505192016694938e-01 0.5 -3.1505192016694938e-01 0] + Gamma=[ gamma 0 0 0; + -8.7173304301691801e-01 gamma 0 0; + -1.2855347382089872e+00 5.0507005541550687e-01 gamma 0; + -4.8201449182864348e-01 2.1793326075422950e-01 -1.7178529043404503e-01 gamma] + B=[3.3303742833830591e-01, 7.1793326075422947e-01, -4.8683721060099439e-01, 4.3586652150845900e-01] + Bhat=[0.25, 7.4276119608319180e-01, -3.1472922970066219e-01, 3.2196803361747034e-01] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_wanner_docstring( +""" +3rd order stiffly accurate Rosenbrock-Wanner W-method with 4 internal stages, +B_PR consistent of order 2. +The order of convergence decreases if medium stiff problems are considered. +""", +"ROS34PRw", +references = """ +- Joachim Rang, Improved traditional Rosenbrock–Wanner methods for stiff ODEs and DAEs, + Journal of Computational and Applied Mathematics, + https://doi.org/10.1016/j.cam.2015.03.010 +""") ROS34PRw + +""" + ROS3PRLTableau() + +3rd order stiffly accurate Rosenbrock-Wanner method with 4 internal stages, +B_PR consistent of order 2 with Rinf=0. +The order of convergence decreases if medium stiff problems are considered, but it has good results for very stiff cases. + +Rang, Joachim (2014): The Prothero and Robinson example: +Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 +""" +function ROS3PRLTableau() # 3rd order + gamma=4.3586652150845900e-01 + Alpha=[0 0 0 0; + 5.00000000000000e-01 0 0 0; + 5.00000000000000e-01 5.00000000000000e-01 0 0; + 5.00000000000000e-01 5.00000000000000e-01 0 0] + Gamma=[ gamma 0 0 0; + -5.00000000000000e-01 gamma 0 0; + -7.91564804204642e-01 3.52442167927514e-01 gamma 0; + -4.97889699145187e-01 3.86075154415805e-01 -3.24051976779077e-01 gamma] + B=[2.11030085481324e-03, 8.86075154415805e-01, -3.24051976779077e-01, 4.35866521508459e-01] + Bhat=[0.5, 3.87524229532982e-01, -2.09492263150452e-01, 3.21968033617470e-01] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_docstring( +""" +3rd order stiffly accurate Rosenbrock method with 4 internal stages, +B_PR consistent of order 2 with Rinf=0. +The order of convergence decreases if medium stiff problems are considered, but it has good results for very stiff cases. +""", +"ROS3PRL", +references = """ +- Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 +""") ROS3PRL + + +""" + ROS3PRL2Tableau() + +3rd order stiffly accurate Rosenbrock method with 4 internal stages, +B_PR consistent of order 3. +The order of convergence does NOT decreases if medium stiff problems are considered as it does for [`ROS3PRL`](@ref). + +Rang, Joachim (2014): The Prothero and Robinson example: +Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 +""" +function ROS3PRL2Tableau() # 3rd order + gamma=4.35866521508459e-01 + Alpha=[0 0 0 0; + 1.30759956452538e+00 0 0 0; + 5.00000000000000e-01 5.00000000000000e-01 0 0; + 5.00000000000000e-01 5.00000000000000e-01 0 0] + Gamma=[gamma 0 0 0; + -1.30759956452538e+00 gamma 0 0; + -7.09885758609722e-01 -5.59967359602778e-01 gamma 0; + -1.55508568075521e-01 -9.53885165751122e-01 6.73527212318184e-01 gamma] + B=[3.44491431924479e-01,-4.53885165751122e-01, 6.73527212318184e-01, 4.35866521508459e-01] + Bhat=[5.00000000000000e-01, -2.57388120865221e-01, 4.35420087247750e-01, 3.21968033617470e-01] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_docstring( +""" +3rd order stiffly accurate Rosenbrock method with 4 internal stages, +B_PR consistent of order 3. +The order of convergence does NOT decreases if medium stiff problems are considered as it does for [`ROS3PRL`](@ref). +""", +"ROS3PRL2", +references = """ +- Rang, Joachim (2014): The Prothero and Robinson example: + Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. + https://doi.org/10.24355/dbbs.084-201408121139-0 +""") ROS3PRL2 + + +""" + ROK4aTableau() + +4rd order L-stable Rosenbrock-Krylov method with 4 internal stages, +with a 3rd order embedded method which is strongly A-stable with Rinf~=0.55. (when using exact Jacobians) +Tranquilli, Paul and Sandu, Adrian (2014): Rosenbrock--Krylov Methods for Large Systems of Differential Equations +https://doi.org/10.1137/130923336 +""" +function ROK4aTableau() # 4rd order + gamma=0.572816062482135 + Alpha=[0 0 0 0; + 1 0 0 0; + 0.10845300169319391758 0.39154699830680608241 0 0; + 0.43453047756004477624 0.14484349252001492541 -0.07937397008005970166 0] + Gamma=[gamma 0 0 0; + -1.91153192976055097824 gamma 0 0; + 0.32881824061153522156 0.0 gamma 0; + 0.03303644239795811290 -0.24375152376108235312 -0.17062602991994029834 gamma] + B= [0.16666666666666666667, 0.16666666666666666667, 0.0, 0.66666666666666666667] + Bhat=[0.50269322573684235345, 0.27867551969005856226, 0.21863125457309908428, 0.0] + a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) + RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) +end + +@doc rosenbrock_wanner_docstring( +""" +4rd order L-stable Rosenbrock-Krylov method with 4 internal stages, +with a 3rd order embedded method which is strongly A-stable with Rinf~=0.55. (when using exact Jacobians) +""", +"ROK4a", +references = """ +- Tranquilli, Paul and Sandu, Adrian (2014): + Rosenbrock--Krylov Methods for Large Systems of Differential Equations + https://doi.org/10.1137/130923336 +""") ROK4a + +""" + @ROS34PW(part) + +Generate code for the 4 steps ROS34PW methods: ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, ROS3PRL2, ROK4a. +`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. +`@ROS34PW(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. +`@ROS34PW(:cache)` should be placed in `caches/rosenbrock_caches.jl`. +`@ROS34PW(:init)` and `@ROS34PW(:performstep)` should be placed in +`perform_step/rosenbrock_perform_step.jl`. +""" +macro ROS34PW(part) + tabmask=Ros34dummyTableau() + cachename=:ROS34PWCache + constcachename=:ROS34PWConstantCache + ROS34PW1atabname=:ROS34PW1aTableau + ROS34PW1btabname=:ROS34PW1bTableau + ROS34PW2tabname=:ROS34PW2Tableau + ROS34PW3tabname=:ROS34PW3Tableau + ROS34PRwtabname=:ROS34PRwTableau + ROS3PRLtabname=:ROS3PRLTableau + ROS3PRL2tabname=:ROS3PRL2Tableau + ROK4atabname=:ROK4aTableau + n_normalstep=length(tabmask.b)-1 + if part.value==:tableau + tabstructexpr=gen_tableau_struct(tabmask,:Ros34Tableau) + tabexprs=Array{Expr,1}([tabstructexpr]) + push!(tabexprs,gen_tableau(ROS34PW1aTableau(),tabstructexpr,ROS34PW1atabname)) + push!(tabexprs,gen_tableau(ROS34PW1bTableau(),tabstructexpr,ROS34PW1btabname)) + push!(tabexprs,gen_tableau(ROS34PW2Tableau(),tabstructexpr,ROS34PW2tabname)) + push!(tabexprs,gen_tableau(ROS34PW3Tableau(),tabstructexpr,ROS34PW3tabname)) + push!(tabexprs,gen_tableau(ROS34PRwTableau(),tabstructexpr,ROS34PRwtabname)) + push!(tabexprs,gen_tableau(ROS3PRLTableau(),tabstructexpr,ROS3PRLtabname)) + push!(tabexprs,gen_tableau(ROS3PRL2Tableau(),tabstructexpr,ROS3PRL2tabname)) + push!(tabexprs,gen_tableau(ROK4aTableau(),tabstructexpr,ROK4atabname)) + return esc(quote $(tabexprs...) end) + elseif part.value==:cache + constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) + cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW1a,ROS34PW1atabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW1b,ROS34PW1btabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW2,ROS34PW2tabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW3,ROS34PW3tabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PRw,ROS34PRwtabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3PRL,ROS3PRLtabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3PRL2,ROS3PRL2tabname)) + push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROK4a,ROK4atabname)) + return esc(quote $(cacheexprs...) end) + elseif part.value==:init + return esc(gen_initialize(cachename,constcachename)) + elseif part.value==:performstep + performstepexprs=Array{Expr,1}() + push!(performstepexprs,gen_constant_perform_step(tabmask,constcachename,n_normalstep)) + push!(performstepexprs,gen_perform_step(tabmask,cachename,n_normalstep)) + return esc(quote $(performstepexprs...) end) + else + throw(ArgumentError("Unknown parameter!")) + nothing + end +end + +#========================================================================================= +# How to add a new method +1. `OrdinaryDiffEq.jl`: export +2. `alg_utils.jl`: alg_order(alg::)= + if the method is a W-method, add isWmethod(alg::) = true as well +3. `algorithms.jl`: add algorithm struct +4. `generic_rosenbrock.jl`: + a. write dummy tableau function (or generate from actual tableau using _masktab) for generating + table struct, cache struct and perform_step + b. write tableau function. When only `Alpha, Gamma, B, Bhat` are given, use _transformtab + c. write macro with :tableau, :cache, :init and :performstep + d. put the macros in the right places. +5. test\algconvergence\ode_rosenbrock_tests.jl: add a test for your method +# How to refactor methods into generic ones +RUN CONVERGENCE TESTS BETWEEN ANY OF THE TWO STEPS! +1. write tableau function and macro definition in this file +2. replace the tableau function (usually named with `XXXConstCache()`) using `gen_tableau()` + and the original tableau struct expression in `tableaus/rosenbrock_tableaus.jl` +3. replace the `perform_step!` methods in `perform_step/rosenbrock_perform_step.jl` using + `gen_perform_step()` and `gen_constant_perform_step()` +4. replace cache struct and `alg_cache` in `caches/rosenbrock_caches.jl` using `gen_cache_struct()` + and `gen_algcache()` +5. If the method only have 3rd-order Hermite interpolation, you can replace `initialize!()` + in `perform_step/rosenbrock_perform_step.jl` with `gen_initialize()` +DONE + +# How to debug +Use macroexpand like `macroexpand(OrdinaryDiffEq,:(@ROS34PW(:performstep)))` and check the +generated codes. + +`Revise.jl` is not compatible with macros. One may want to manually re-eval files that use +the macro like `@eval OrdinaryDiffEq include(...)` + +# If you want to refactor Rosenbrock methods ... +You need to change respective places in this file. +1. `perform_step/rosenbrock_perform_step.jl` -> `gen_perform_step()`, `gen_constant_perform_step()`, + `gen_initialize()` and special step expressions in macro definitions +2. `caches/rosenbrock_caches.jl` -> `gen_algcache()`, `gen_cache_struct()` +3. `tableaus/rosenbrock_tableaus.jl` -> `gen_tableau_struct()` and `gen_tableau()` +=========================================================================================# diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index 97c74f9cf1..416a6ea99d 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -393,6 +393,32 @@ end struct PredictiveController <: AbstractController end +@inline function stepsize_controller!(integrator, controller::PredictiveController, alg) + @unpack qmin, qmax, gamma = integrator.opts + EEst = DiffEqBase.value(integrator.EEst) + + if iszero(EEst) + q = inv(qmax) + else + if fac_default_gamma(alg) + fac = gamma + else + if alg isa Union{RadauIIA3, RadauIIA5} + @unpack iter = integrator.cache + @unpack maxiters = alg + else + @unpack iter, maxiters = integrator.cache.nlsolver + end + fac = min(gamma, (1 + 2 * maxiters) * gamma / (iter + 2 * maxiters)) + end + expo = 1 / (get_current_adaptive_order(alg, integrator.cache) + 1) + qtmp = DiffEqBase.fastpow(EEst, expo) / fac + @fastmath q = DiffEqBase.value(max(inv(qmax), min(inv(qmin), qtmp))) + integrator.qold = q + end + q +end + function step_accept_controller!(integrator, controller::PredictiveController, alg, q) @unpack qmin, qmax, gamma, qsteady_min, qsteady_max = integrator.opts EEst = DiffEqBase.value(integrator.EEst) diff --git a/src/integrators/integrator_interface.jl b/src/integrators/integrator_interface.jl index 3a14aa13bf..5bf13dc578 100644 --- a/src/integrators/integrator_interface.jl +++ b/src/integrators/integrator_interface.jl @@ -87,6 +87,26 @@ end end end +@inline function DiffEqBase.get_du!(out, integrator::ODEIntegrator) + integrator.cache isa FunctionMapCache || + integrator.cache isa FunctionMapConstantCache && + error("Derivatives are not defined for this stepper.") + if integrator.cache isa FunctionMapCache + out .= integrator.cache.tmp + else + return if isdefined(integrator, :fsallast) && + !(integrator.alg isa + Union{Rosenbrock23, Rosenbrock32, Rodas23W, + Rodas3P, Rodas4, Rodas4P, Rodas4P2, Rodas5, + Rodas5P, Rodas5Pe, Rodas5Pr}) + # Special stiff interpolations do not store the right value in fsallast + out .= integrator.fsallast + else + integrator(out, integrator.t, Val{1}) + end + end +end + #TODO: Bigger caches for most algorithms @inline function DiffEqBase.get_tmp_cache(integrator::ODEIntegrator) get_tmp_cache(integrator::ODEIntegrator, integrator.alg, integrator.cache) @@ -104,6 +124,10 @@ end cache::OrdinaryDiffEqMutableCache) (cache.tmp,) end +@inline function DiffEqBase.get_tmp_cache(integrator, alg::Union{RadauIIA3, RadauIIA5}, + cache::OrdinaryDiffEqMutableCache) + (cache.tmp, cache.atmp) +end @inline function DiffEqBase.get_tmp_cache(integrator, alg::OrdinaryDiffEqNewtonAdaptiveAlgorithm, cache::OrdinaryDiffEqMutableCache) @@ -113,6 +137,11 @@ end cache::OrdinaryDiffEqMutableCache) (cache.nlsolver.tmp, cache.nlsolver.z) end +@inline function DiffEqBase.get_tmp_cache(integrator, + alg::OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, + cache::OrdinaryDiffEqMutableCache) + (cache.tmp, cache.linsolve_tmp) +end @inline function DiffEqBase.get_tmp_cache(integrator, alg::OrdinaryDiffEqAdaptiveExponentialAlgorithm, @@ -303,6 +332,15 @@ function addat_non_user_cache!(integrator::ODEIntegrator, cache::CompositeCache, end end +function resize_non_user_cache!(integrator::ODEIntegrator, + cache::RosenbrockMutableCache, i) + cache.J = similar(cache.J, i, i) + cache.W = similar(cache.W, i, i) + resize_jac_config!(cache.jac_config, i) + resize_grad_config!(cache.grad_config, i) + nothing +end + function deleteat_non_user_cache!(integrator::ODEIntegrator, cache, idxs) # ordering doesn't matter in deterministic cache, so just resize # to match the size of u diff --git a/src/integrators/integrator_utils.jl b/src/integrators/integrator_utils.jl index f0033ca462..a3f45f456a 100644 --- a/src/integrators/integrator_utils.jl +++ b/src/integrators/integrator_utils.jl @@ -380,6 +380,39 @@ function update_uprev!(integrator) nothing end +function apply_step!(integrator) + update_uprev!(integrator) + + #Update dt if adaptive or if fixed and the dt is allowed to change + if integrator.opts.adaptive || integrator.dtchangeable + integrator.dt = integrator.dtpropose + elseif integrator.dt != integrator.dtpropose && !integrator.dtchangeable + error("The current setup does not allow for changing dt.") + end + + # Update fsal if needed + if has_discontinuity(integrator) && + first_discontinuity(integrator) == integrator.tdir * integrator.t + handle_discontinuities!(integrator) + get_current_isfsal(integrator.alg, integrator.cache) && reset_fsal!(integrator) + elseif all_fsal(integrator.alg, integrator.cache) || + get_current_isfsal(integrator.alg, integrator.cache) + if integrator.reeval_fsal || integrator.u_modified || + (integrator.alg isa DP8 && !integrator.opts.calck) || + (integrator.alg isa Union{Rosenbrock23, Rosenbrock32} && + !integrator.opts.adaptive) + reset_fsal!(integrator) + else # Do not reeval_fsal, instead copyto! over + if isinplace(integrator.sol.prob) + recursivecopy!(integrator.fsalfirst, integrator.fsallast) + else + integrator.fsalfirst = integrator.fsallast + end + end + end + return nothing +end + handle_discontinuities!(integrator) = pop_discontinuity!(integrator) function calc_dt_propose!(integrator, dtnew) diff --git a/src/interp_func.jl b/src/interp_func.jl index 8cc95ac156..b1c364c734 100644 --- a/src/interp_func.jl +++ b/src/interp_func.jl @@ -30,6 +30,85 @@ function DiffEqBase.interp_summary(interp::OrdinaryDiffEqInterpolation{ } DiffEqBase.interp_summary(cacheType, interp.dense) end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where {cacheType <: + FunctionMapConstantCache} + "left-endpoint piecewise constant" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where {cacheType <: FunctionMapCache} + "left-endpoint piecewise constant" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{DP5ConstantCache, DP5Cache}} + dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Rosenbrock23ConstantCache, + Rosenbrock32ConstantCache, + Rosenbrock23Cache, + Rosenbrock32Cache}} + dense ? "specialized 2nd order \"free\" stiffness-aware interpolation" : + "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache, + Rodas4Cache, Rodas23WCache, Rodas3PCache}} + dense ? "specialized 3rd order \"free\" stiffness-aware interpolation" : + "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Rosenbrock5ConstantCache, + Rosenbrock5Cache}} + dense ? "specialized 4rd order \"free\" stiffness-aware interpolation" : + "1st order linear" +end + +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: Union{OwrenZen3Cache, + OwrenZen3ConstantCache}} + dense ? "specialized 3rd order \"free\" interpolation" : "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: Union{OwrenZen4Cache, + OwrenZen4ConstantCache}} + dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: Union{OwrenZen5Cache, + OwrenZen5ConstantCache}} + dense ? "specialized 5th order \"free\" interpolation" : "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{Tsit5Cache, Tsit5ConstantCache +}} + dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{BS5ConstantCache, BS5Cache}} + dense ? "specialized 5th order lazy interpolation" : "1st order linear" +end +function DiffEqBase.interp_summary(::Type{cacheType}, + dense::Bool) where { + cacheType <: + Union{DP8ConstantCache, DP8Cache}} + dense ? "specialized 7th order interpolation" : "1st order linear" +end function DiffEqBase.interp_summary(::Type{cacheType}, dense::Bool) where {cacheType} dense ? "3rd order Hermite" : "1st order linear" end diff --git a/src/perform_step/bdf_perform_step.jl b/src/perform_step/bdf_perform_step.jl new file mode 100644 index 0000000000..e52686c8cc --- /dev/null +++ b/src/perform_step/bdf_perform_step.jl @@ -0,0 +1,1345 @@ +function initialize!(integrator, cache::ABDF2ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::ABDF2ConstantCache, repeat_step = false) + @unpack t, f, p = integrator + @unpack dtₙ₋₁, nlsolver = cache + alg = unwrap_alg(integrator, true) + dtₙ, uₙ, uₙ₋₁, uₙ₋₂ = integrator.dt, integrator.u, integrator.uprev, integrator.uprev2 + + # TODO: this doesn't look right + if integrator.iter == 1 && !integrator.u_modified + cache.dtₙ₋₁ = dtₙ + cache.eulercache.nlsolver.method = DIRK + perform_step!(integrator, cache.eulercache, repeat_step) + cache.fsalfirstprev = integrator.fsalfirst + return + end + + fₙ₋₁ = integrator.fsalfirst + ρ = dtₙ / dtₙ₋₁ + β₀ = 2 // 3 + β₁ = -(ρ - 1) / 3 + α₀ = 1 + α̂ = ρ^2 / 3 + α₁ = 1 + α̂ + α₂ = -α̂ + + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + u = @.. broadcast=false uₙ₋₁+dtₙ * fₙ₋₁ + else # :constant + u = uₙ₋₁ + end + nlsolver.z = u + + mass_matrix = f.mass_matrix + + if mass_matrix === I + nlsolver.tmp = @.. broadcast=false ((dtₙ * β₁) * fₙ₋₁ + + (α₁ * uₙ₋₁ + α₂ * uₙ₋₂))/(dtₙ * + β₀) + else + _tmp = mass_matrix * @.. broadcast=false (α₁ * uₙ₋₁+α₂ * uₙ₋₂) + nlsolver.tmp = @.. broadcast=false ((dtₙ * β₁) * fₙ₋₁ + _tmp)/(dtₙ * β₀) + end + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + uₙ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + integrator.fsallast = f(uₙ, p, t + dtₙ) + integrator.stats.nf += 1 + + if integrator.opts.adaptive + tmp = integrator.fsallast - (1 + dtₙ / dtₙ₋₁) * integrator.fsalfirst + + (dtₙ / dtₙ₋₁) * cache.fsalfirstprev + est = (dtₙ₋₁ + dtₙ) / 6 * tmp + atmp = calculate_residuals(est, uₙ₋₁, uₙ, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + ################################### Finalize + + if integrator.EEst < one(integrator.EEst) + cache.fsalfirstprev = integrator.fsalfirst + cache.dtₙ₋₁ = dtₙ + end + + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = uₙ + return +end + +function initialize!(integrator, cache::ABDF2Cache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::ABDF2Cache, repeat_step = false) + @unpack t, dt, f, p = integrator + #TODO: remove zₙ₋₁ from the cache + @unpack atmp, dtₙ₋₁, zₙ₋₁, nlsolver, step_limiter! = cache + @unpack z, tmp, ztmp = nlsolver + alg = unwrap_alg(integrator, true) + uₙ, uₙ₋₁, uₙ₋₂, dtₙ = integrator.u, integrator.uprev, integrator.uprev2, integrator.dt + + if integrator.iter == 1 && !integrator.u_modified + cache.dtₙ₋₁ = dtₙ + cache.eulercache.nlsolver.method = DIRK + perform_step!(integrator, cache.eulercache, repeat_step) + cache.fsalfirstprev .= integrator.fsalfirst + nlsolver.tmp = tmp + return + end + + fₙ₋₁ = integrator.fsalfirst + ρ = dtₙ / dtₙ₋₁ + β₀ = 2 // 3 + β₁ = -(ρ - 1) / 3 + α₀ = 1 + α̂ = ρ^2 / 3 + α₁ = 1 + α̂ + α₂ = -α̂ + + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + @.. broadcast=false z=uₙ₋₁ + dtₙ * fₙ₋₁ + else # :constant + @.. broadcast=false z=uₙ₋₁ + end + + mass_matrix = f.mass_matrix + + if mass_matrix === I + @.. broadcast=false tmp=((dtₙ * β₁) * fₙ₋₁ + (α₁ * uₙ₋₁ + α₂ * uₙ₋₂)) / (dtₙ * β₀) + else + dz = nlsolver.cache.dz + @.. broadcast=false dz=α₁ * uₙ₋₁ + α₂ * uₙ₋₂ + mul!(ztmp, mass_matrix, dz) + @.. broadcast=false tmp=((dtₙ * β₁) * fₙ₋₁ + ztmp) / (dtₙ * β₀) + end + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false uₙ=z + + step_limiter!(uₙ, integrator, p, t + dtₙ) + + f(integrator.fsallast, uₙ, p, t + dtₙ) + integrator.stats.nf += 1 + if integrator.opts.adaptive + btilde0 = (dtₙ₋₁ + dtₙ) * 1 // 6 + btilde1 = 1 + dtₙ / dtₙ₋₁ + btilde2 = dtₙ / dtₙ₋₁ + @.. broadcast=false tmp=btilde0 * + (integrator.fsallast - btilde1 * integrator.fsalfirst + + btilde2 * cache.fsalfirstprev) + calculate_residuals!(atmp, tmp, uₙ₋₁, uₙ, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + ################################### Finalize + + if integrator.EEst < one(integrator.EEst) + @.. broadcast=false cache.fsalfirstprev=integrator.fsalfirst + cache.dtₙ₋₁ = dtₙ + end + return +end + +# SBDF + +function initialize!(integrator, cache::SBDFConstantCache) + @unpack uprev, p, t = integrator + @unpack f1, f2 = integrator.f + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + cache.du₁ = f1(uprev, p, t) + cache.du₂ = f2(uprev, p, t) + integrator.stats.nf += 1 + integrator.stats.nf2 += 1 + integrator.fsalfirst = cache.du₁ + cache.du₂ + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::SBDFConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + alg = unwrap_alg(integrator, true) + @unpack uprev2, uprev3, uprev4, du₁, du₂, k₁, k₂, k₃, nlsolver = cache + @unpack f1, f2 = integrator.f + cnt = cache.cnt = min(alg.order, integrator.iter + 1) + integrator.iter == 1 && !integrator.u_modified && (cnt = cache.cnt = 1) + nlsolver.γ = γ = inv(γₖ[cnt]) + if cache.ark + # Additive Runge-Kutta Method + du₂ = f2(uprev + dt * du₁, p, t) + integrator.stats.nf2 += 1 + end + if cnt == 1 + tmp = uprev + dt * du₂ + elseif cnt == 2 + tmp = γ * (2 * uprev - 1 // 2 * uprev2 + dt * (2 * du₂ - k₁)) + elseif cnt == 3 + tmp = γ * + (3 * uprev - 3 // 2 * uprev2 + 1 // 3 * uprev3 + dt * (3 * (du₂ - k₁) + k₂)) + else + tmp = γ * (4 * uprev - 3 * uprev2 + 4 // 3 * uprev3 - 1 // 4 * uprev4 + + dt * (4 * du₂ - 6 * k₁ + 4 * k₂ - k₃)) + end + nlsolver.tmp = tmp + + # Implicit part + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + z = dt * du₁ + else # :constant + z = zero(u) + end + nlsolver.z = z + + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = nlsolver.tmp + γ * z + + cnt == 4 && (cache.uprev4 = uprev3; + cache.k₃ = k₂) + cnt >= 3 && (cache.uprev3 = uprev2; + cache.k₂ = k₁) + (cache.uprev2 = uprev; + cache.k₁ = du₂) + cache.du₁ = f1(u, p, t + dt) + cache.du₂ = f2(u, p, t + dt) + integrator.stats.nf += 1 + integrator.stats.nf2 += 1 + integrator.fsallast = cache.du₁ + cache.du₂ + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::SBDFCache) + @unpack uprev, p, t = integrator + @unpack f1, f2 = integrator.f + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + f1(cache.du₁, uprev, p, t) + f2(cache.du₂, uprev, p, t) + integrator.stats.nf += 1 + integrator.stats.nf2 += 1 + @.. broadcast=false integrator.fsalfirst=cache.du₁ + cache.du₂ +end + +function perform_step!(integrator, cache::SBDFCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + alg = unwrap_alg(integrator, true) + @unpack uprev2, uprev3, uprev4, k₁, k₂, k₃, du₁, du₂, nlsolver = cache + @unpack tmp, z = nlsolver + @unpack f1, f2 = integrator.f + cnt = cache.cnt = min(alg.order, integrator.iter + 1) + integrator.iter == 1 && !integrator.u_modified && (cnt = cache.cnt = 1) + nlsolver.γ = γ = inv(γₖ[cnt]) + # Explicit part + if cache.ark + # Additive Runge-Kutta Method + f2(du₂, uprev + dt * du₁, p, t) + integrator.stats.nf2 += 1 + end + if cnt == 1 + @.. broadcast=false tmp=uprev + dt * du₂ + elseif cnt == 2 + @.. broadcast=false tmp=γ * (2 * uprev - 1 // 2 * uprev2 + dt * (2 * du₂ - k₁)) + elseif cnt == 3 + @.. broadcast=false tmp=γ * (3 * uprev - 3 // 2 * uprev2 + 1 // 3 * uprev3 + + dt * (3 * (du₂ - k₁) + k₂)) + else + @.. broadcast=false tmp=γ * (4 * uprev - 3 * uprev2 + 4 // 3 * uprev3 - + 1 // 4 * uprev4 + dt * (4 * du₂ - 6 * k₁ + 4 * k₂ - k₃)) + end + # Implicit part + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + @.. broadcast=false z=dt * du₁ + else # :constant + @.. broadcast=false z=zero(eltype(u)) + end + + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=tmp + γ * z + + cnt == 4 && (cache.uprev4 .= uprev3; + cache.k₃ .= k₂) + cnt >= 3 && (cache.uprev3 .= uprev2; + cache.k₂ .= k₁) + (cache.uprev2 .= uprev; + cache.k₁ .= du₂) + f1(du₁, u, p, t + dt) + f2(du₂, u, p, t + dt) + integrator.stats.nf += 1 + integrator.stats.nf2 += 1 + @.. broadcast=false integrator.fsallast=du₁ + du₂ +end + +# QNDF1 + +function initialize!(integrator, cache::QNDF1ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::QNDF1ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack uprev2, D, D2, R, U, dtₙ₋₁, nlsolver = cache + alg = unwrap_alg(integrator, true) + κ = alg.kappa + cnt = integrator.iter + k = 1 + if cnt > 1 + ρ = dt / dtₙ₋₁ + D[1] = uprev - uprev2 # backward diff + if ρ != 1 + R!(k, ρ, cache) + R .= R * U + D[1] = D[1] * R[1, 1] + end + else + κ = zero(alg.kappa) + end + + #Changing uprev2 after D Array has changed with step-size + uprev2 = uprev - D[1] + + β₀ = 1 + α₀ = 1 - κ + α₁ = 1 - 2 * κ + α₂ = κ + + markfirststage!(nlsolver) + + # initial guess + nlsolver.z = uprev + sum(D) + + mass_matrix = f.mass_matrix + + if mass_matrix === I + nlsolver.tmp = @.. broadcast=false (α₁ * uprev + α₂ * uprev2)/(dt * β₀) + else + _tmp = mass_matrix * @.. broadcast=false (α₁ * uprev+α₂ * uprev2) + nlsolver.tmp = @.. broadcast=false _tmp/(dt * β₀) + end + + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + + u = nlsolve!(nlsolver, integrator, cache, repeat_step) + + nlsolvefail(nlsolver) && return + if integrator.opts.adaptive + if integrator.success_iter == 0 + integrator.EEst = one(integrator.EEst) + else + D2[1] = u - uprev + D2[2] = D2[1] - D[1] + utilde = (κ + inv(k + 1)) * D2[2] + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, + t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + end + if integrator.EEst > one(integrator.EEst) + return + end + cache.dtₙ₋₁ = dt + cache.uprev2 = uprev + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +function initialize!(integrator, cache::QNDF1Cache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::QNDF1Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack uprev2, D, D2, R, U, dtₙ₋₁, utilde, atmp, nlsolver, step_limiter! = cache + @unpack z, tmp, ztmp = nlsolver + alg = unwrap_alg(integrator, true) + κ = alg.kappa + cnt = integrator.iter + k = 1 + if cnt > 1 + ρ = dt / dtₙ₋₁ + @.. broadcast=false D[1]=uprev - uprev2 # backward diff + if ρ != 1 + R!(k, ρ, cache) + R .= R * U + @.. broadcast=false D[1]=D[1] * R[1, 1] + end + else + κ = zero(alg.kappa) + end + + #Changing uprev2 after D Array has changed with step-size + uprev2 = uprev - D[1] + + β₀ = 1 + α₀ = 1 - κ + α₁ = 1 - 2 * κ + α₂ = κ + + markfirststage!(nlsolver) + + # initial guess + nlsolver.z = uprev + sum(D) + + mass_matrix = f.mass_matrix + + if mass_matrix === I + @.. broadcast=false tmp=(α₁ * uprev + α₂ * uprev2) / (dt * β₀) + else + dz = nlsolver.cache.dz + @.. broadcast=false dz=α₁ * uprev + α₂ * uprev2 + mul!(ztmp, mass_matrix, dz) + @.. broadcast=false tmp=ztmp / (dt * β₀) + end + + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=z + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + if integrator.success_iter == 0 + integrator.EEst = one(integrator.EEst) + else + @.. broadcast=false D2[1]=u - uprev + @.. broadcast=false D2[2]=D2[1] - D[1] + @.. broadcast=false utilde=(κ + inv(k + 1)) * D2[2] + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + end + if integrator.EEst > one(integrator.EEst) + return + end + cache.uprev2 .= uprev + cache.dtₙ₋₁ = dt + f(integrator.fsallast, u, p, t + dt) + integrator.stats.nf += 1 + return +end + +function initialize!(integrator, cache::QNDF2ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::QNDF2ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack uprev2, uprev3, dtₙ₋₁, dtₙ₋₂, D, D2, R, U, nlsolver = cache + alg = unwrap_alg(integrator, true) + cnt = integrator.iter + k = 2 + if cnt == 1 || cnt == 2 + κ = zero(alg.kappa) + γ₁ = 1 // 1 + γ₂ = 1 // 1 + elseif dtₙ₋₁ != dtₙ₋₂ + κ = alg.kappa + γ₁ = 1 // 1 + γ₂ = 1 // 1 + 1 // 2 + ρ₁ = dt / dtₙ₋₁ + ρ₂ = dt / dtₙ₋₂ + D[1] = uprev - uprev2 + D[1] = D[1] * ρ₁ + D[2] = D[1] - ((uprev2 - uprev3) * ρ₂) + else + κ = alg.kappa + γ₁ = 1 // 1 + γ₂ = 1 // 1 + 1 // 2 + ρ = dt / dtₙ₋₁ + # backward diff + D[1] = uprev - uprev2 + D[2] = D[1] - (uprev2 - uprev3) + if ρ != 1 + R!(k, ρ, cache) + R .= R * U + D[1] = D[1] * R[1, 1] + D[2] * R[2, 1] + D[2] = D[1] * R[1, 2] + D[2] * R[2, 2] + end + end + + β₀ = inv((1 - κ) * γ₂) + α₀ = 1 + + u₀ = uprev + D[1] + D[2] + ϕ = (γ₁ * D[1] + γ₂ * D[2]) * β₀ + + markfirststage!(nlsolver) + + # initial guess + nlsolver.z = uprev + sum(D) + + mass_matrix = f.mass_matrix + + if mass_matrix === I + nlsolver.tmp = @.. broadcast=false (u₀ - ϕ)/(dt * β₀) + else + _tmp = mass_matrix * @.. broadcast=false (u₀-ϕ) + nlsolver.tmp = @.. broadcast=false _tmp/(dt * β₀) + end + + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + + u = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + if integrator.opts.adaptive + if integrator.success_iter == 0 + integrator.EEst = one(integrator.EEst) + elseif integrator.success_iter == 1 + utilde = (u - uprev) - ((uprev - uprev2) * dt / dtₙ₋₁) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, + t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + D2[1] = u - uprev + D2[2] = D2[1] - D[1] + D2[3] = D2[2] - D[2] + utilde = (κ * γ₂ + inv(k + 1)) * D2[3] + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, + t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + end + if integrator.EEst > one(integrator.EEst) + return + end + + cache.uprev3 = uprev2 + cache.uprev2 = uprev + cache.dtₙ₋₂ = dtₙ₋₁ + cache.dtₙ₋₁ = dt + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +function initialize!(integrator, cache::QNDF2Cache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::QNDF2Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack uprev2, uprev3, dtₙ₋₁, dtₙ₋₂, D, D2, R, U, utilde, atmp, nlsolver, step_limiter! = cache + @unpack z, tmp, ztmp = nlsolver + alg = unwrap_alg(integrator, true) + cnt = integrator.iter + k = 2 + if cnt == 1 || cnt == 2 + κ = zero(alg.kappa) + γ₁ = 1 // 1 + γ₂ = 1 // 1 + elseif dtₙ₋₁ != dtₙ₋₂ + κ = alg.kappa + γ₁ = 1 // 1 + γ₂ = 1 // 1 + 1 // 2 + ρ₁ = dt / dtₙ₋₁ + ρ₂ = dt / dtₙ₋₂ + @.. broadcast=false D[1]=uprev - uprev2 + @.. broadcast=false D[1]=D[1] * ρ₁ + @.. broadcast=false D[2]=D[1] - ((uprev2 - uprev3) * ρ₂) + else + κ = alg.kappa + γ₁ = 1 // 1 + γ₂ = 1 // 1 + 1 // 2 + ρ = dt / dtₙ₋₁ + # backward diff + @.. broadcast=false D[1]=uprev - uprev2 + @.. broadcast=false D[2]=D[1] - (uprev2 - uprev3) + if ρ != 1 + R!(k, ρ, cache) + R .= R * U + @.. broadcast=false D[1]=D[1] * R[1, 1] + D[2] * R[2, 1] + @.. broadcast=false D[2]=D[1] * R[1, 2] + D[2] * R[2, 2] + end + end + + β₀ = inv((1 - κ) * γ₂) + α₀ = 1 + + u₀ = uprev + D[1] + D[2] + ϕ = (γ₁ * D[1] + γ₂ * D[2]) * β₀ + + markfirststage!(nlsolver) + + # initial guess + nlsolver.z = uprev + sum(D) + + mass_matrix = f.mass_matrix + + if mass_matrix === I + @.. broadcast=false tmp=(u₀ - ϕ) / (dt * β₀) + else + dz = nlsolver.cache.dz + @.. broadcast=false dz=u₀ - ϕ + mul!(ztmp, mass_matrix, dz) + @.. broadcast=false tmp=ztmp / (dt * β₀) + end + + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=z + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + if integrator.success_iter == 0 + integrator.EEst = one(integrator.EEst) + elseif integrator.success_iter == 1 + @.. broadcast=false utilde=(u - uprev) - ((uprev - uprev2) * dt / dtₙ₋₁) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + @.. broadcast=false D2[1]=u - uprev + @.. broadcast=false D2[2]=D2[1] - D[1] + @.. broadcast=false D2[3]=D2[2] - D[2] + @.. broadcast=false utilde=(κ * γ₂ + inv(k + 1)) * D2[3] + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + end + if integrator.EEst > one(integrator.EEst) + return + end + + cache.uprev3 .= uprev2 + cache.uprev2 .= uprev + cache.dtₙ₋₂ = dtₙ₋₁ + cache.dtₙ₋₁ = dt + f(integrator.fsallast, u, p, t + dt) + integrator.stats.nf += 1 + return +end + +function initialize!(integrator, cache::QNDFConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::QNDFConstantCache{max_order}, + repeat_step = false) where {max_order} + @unpack t, dt, uprev, u, f, p = integrator + @unpack dtprev, order, D, U, nlsolver, γₖ = cache + alg = unwrap_alg(integrator, true) + + if integrator.u_modified + dtprev = one(dt) + order = 1 + cache.nconsteps = 0 + cache.consfailcnt = 0 + fill!(D, zero(eltype(D))) + fill!(cache.prevD, zero(eltype(D))) + end + + k = order + κlist = alg.kappa + κ = κlist[k] + if cache.consfailcnt > 0 + copyto!(D, cache.prevD) + end + if dt != dtprev || cache.prevorder != k + ρ = dt / dtprev + integrator.cache.nconsteps = 0 + @unpack U = cache + R = calc_R(ρ, k, Val(max_order)) + RU = R * U + Dtmp = D[:, 1:k] * RU[1:k, 1:k] + D[:, 1:k] = Dtmp + end + + α₀ = 1 + β₀ = inv((1 - κ) * γₖ[k]) + if u isa Number + u₀ = sum(D[1:k]) + uprev + ϕ = zero(u) + for i in 1:k + ϕ += γₖ[i] * D[i] + end + else + u₀ = reshape(sum(D[:, 1:k], dims = 2) .+ uprev, size(u)) + ϕ = zero(u) + for i in 1:k + @.. broadcast=false ϕ+=γₖ[i] * D[:, i] + end + end + markfirststage!(nlsolver) + nlsolver.z = u₀ + mass_matrix = f.mass_matrix + + if mass_matrix === I + nlsolver.tmp = @.. broadcast=false (u₀ / β₀ - ϕ)/dt + else + nlsolver.tmp = mass_matrix * @.. broadcast=false (u₀ / β₀ - ϕ)/dt + end + + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = z + dd = u - u₀ + update_D!(D, dd, k) + + if integrator.opts.adaptive + @unpack abstol, reltol, internalnorm = integrator.opts + if cache.consfailcnt > 1 && mass_matrix !== I + # if we get repeated failure and mass_matrix !== I it's likely that + # there's a discontinuity on the algebraic equations + atmp = calculate_residuals(mass_matrix * dd, uprev, u, abstol, reltol, + internalnorm, t) + else + atmp = calculate_residuals(dd, uprev, u, abstol, reltol, internalnorm, t) + end + integrator.EEst = error_constant(integrator, k) * internalnorm(atmp, t) + if k > 1 + @views atmpm1 = calculate_residuals(D[:, k], uprev, u, integrator.opts.abstol, + integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.EEst1 = error_constant(integrator, k - 1) * internalnorm(atmpm1, t) + end + if k < max_order + @views atmpp1 = calculate_residuals(D[:, k + 2], uprev, u, abstol, reltol, + internalnorm, t) + cache.EEst2 = error_constant(integrator, k + 1) * internalnorm(atmpp1, t) + end + end + if integrator.EEst <= one(integrator.EEst) + copyto!(cache.prevD, D) + cache.dtprev = dt + cache.prevorder = k + if integrator.opts.dense + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + end + end + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::QNDFCache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::QNDFCache{max_order}, + repeat_step = false) where {max_order} + @unpack t, dt, uprev, u, f, p = integrator + @unpack dtprev, order, D, nlsolver, γₖ, dd, atmp, atmpm1, atmpp1, utilde, utildem1, utildep1, ϕ, u₀, step_limiter! = cache + alg = unwrap_alg(integrator, true) + + if integrator.u_modified + dtprev = one(dt) + order = 1 + cache.nconsteps = 0 + cache.consfailcnt = 0 + fill!(D, zero(eltype(D))) + fill!(cache.prevD, zero(eltype(D))) + end + + k = order + κlist = alg.kappa + κ = κlist[k] + if cache.consfailcnt > 0 + copyto!(D, cache.prevD) + end + if dt != dtprev || cache.prevorder != k + ρ = dt / dtprev + cache.nconsteps = 0 + @unpack RU, U, Dtmp = cache + R = calc_R(ρ, k, Val(max_order)) + copyto!(RU, R * U) + @views mul!(Dtmp[:, 1:k], D[:, 1:k], RU[1:k, 1:k]) + D, Dtmp = Dtmp, D + cache.D = D + cache.Dtmp = Dtmp + end + + α₀ = 1 + β₀ = inv((1 - κ) * γₖ[k]) + # D[:, j] contains scaled j-th derivative approximation. + # Thus, it’s likely that ||D[:, j+1]|| <= ||D[:, j]|| holds, + # we want to sum small numbers first to minimize the accumulation error. + # Hence, we sum it backwards. + @inbounds for i in 1:length(u₀) + s = D[i, k] + @simd for j in (k - 1):-1:1 + s += D[i, j] + end + u₀[i] = s + uprev[i] + end + @.. broadcast=false ϕ=zero(u) + vecϕ = _vec(ϕ) + for i in 1:k + @views @.. broadcast=false vecϕ+=γₖ[i] * D[:, i] + end + markfirststage!(nlsolver) + @.. broadcast=false nlsolver.z=u₀ + mass_matrix = f.mass_matrix + + if mass_matrix === I + @.. broadcast=false nlsolver.tmp=(u₀ / β₀ - ϕ) / dt + else + @unpack tmp2 = cache + @.. broadcast=false tmp2=(u₀ / β₀ - ϕ) / dt + mul!(nlsolver.tmp, mass_matrix, tmp2) + end + + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=z + @.. broadcast=false dd=u - u₀ + update_D!(D, dd, k) + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + @unpack abstol, reltol, internalnorm = integrator.opts + if cache.consfailcnt > 1 && mass_matrix !== I + # if we get repeated failure and mass_matrix !== I it's likely that + # there's a discontinuity on the algebraic equations + calculate_residuals!(atmp, mul!(nlsolver.tmp, mass_matrix, dd), uprev, u, + abstol, reltol, internalnorm, t) + else + calculate_residuals!(atmp, dd, uprev, u, abstol, reltol, internalnorm, t) + end + integrator.EEst = error_constant(integrator, k) * internalnorm(atmp, t) + if k > 1 + @views calculate_residuals!( + atmpm1, reshape(D[:, k], size(u)), uprev, u, abstol, + reltol, internalnorm, t) + cache.EEst1 = error_constant(integrator, k - 1) * internalnorm(atmpm1, t) + end + if k < max_order + @views calculate_residuals!( + atmpp1, reshape(D[:, k + 2], size(u)), uprev, u, abstol, + reltol, internalnorm, t) + cache.EEst2 = error_constant(integrator, k + 1) * internalnorm(atmpp1, t) + end + end + if integrator.EEst <= one(integrator.EEst) + copyto!(cache.prevD, D) + cache.dtprev = dt + cache.prevorder = k + if integrator.opts.dense + f(integrator.fsallast, u, p, t + dt) + integrator.stats.nf += 1 + end + end + return nothing +end + +### MEBDF2 +function initialize!(integrator, cache::MEBDF2ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::MEBDF2ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + nlsolver.z = dt * integrator.fsalfirst + else # :constant + nlsolver.z = zero(u) + end + + ### STEP 1 + nlsolver.tmp = uprev + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + z₁ = nlsolver.tmp + z + ### STEP 2 + nlsolver.tmp = z₁ + nlsolver.c = 2 + isnewton(nlsolver) && set_new_W!(nlsolver, false) + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + z₂ = z₁ + z + ### STEP 3 + tmp2 = 0.5uprev + z₁ - 0.5z₂ + nlsolver.tmp = tmp2 + nlsolver.c = 1 + isnewton(nlsolver) && set_new_W!(nlsolver, false) + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = tmp2 + z + + ### finalize + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::MEBDF2Cache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::MEBDF2Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, tmp2, nlsolver = cache + z = nlsolver.z + mass_matrix = integrator.f.mass_matrix + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + @.. broadcast=false z=dt * integrator.fsalfirst + else # :constant + z .= zero(eltype(u)) + end + + ### STEP 1 + nlsolver.tmp = uprev + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false z₁=uprev + z + ### STEP 2 + nlsolver.tmp = z₁ + nlsolver.c = 2 + isnewton(nlsolver) && set_new_W!(nlsolver, false) + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false z₂=z₁ + z + ### STEP 3 + # z .= zero(eltype(u)) + @.. broadcast=false tmp2=0.5uprev + z₁ - 0.5z₂ + nlsolver.tmp = tmp2 + nlsolver.c = 1 + isnewton(nlsolver) && set_new_W!(nlsolver, false) + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=tmp2 + z + + ### finalize + f(integrator.fsallast, u, p, t + dt) + integrator.stats.nf += 1 +end + +function initialize!(integrator, cache::FBDFConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::FBDFConstantCache{max_order}, + repeat_step = false) where {max_order} + @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, ts_tmp, iters_from_event, nconsteps = cache + @unpack t, dt, u, f, p, uprev = integrator + + tdt = t + dt + k = order + reinitFBDF!(integrator, cache) + u₀ = zero(u) + if iters_from_event >= 1 + u₀ = calc_Lagrange_interp(k, weights, tdt, ts, u_history, u₀) + else + u₀ = u + end + markfirststage!(nlsolver) + + nlsolver.z = u₀ + mass_matrix = f.mass_matrix + + equi_ts = zeros(k - 1) + for i in 1:(k - 1) + equi_ts[i] = t - dt * i + end + + fill!(u_corrector, zero(eltype(u))) + if u isa Number + for i in 1:(k - 1) + u_corrector[i] = calc_Lagrange_interp(k, weights, equi_ts[i], ts, u_history, + u_corrector[i]) + end + tmp = -uprev * bdf_coeffs[k, 2] + for i in 1:(k - 1) + tmp -= u_corrector[i] * bdf_coeffs[k, i + 2] + end + else + for i in 1:(k - 1) + @.. broadcast=false @views u_corrector[:, i] = $calc_Lagrange_interp( + k, weights, + equi_ts[i], + ts, + u_history, + u_corrector[:, + i]) + end + tmp = -uprev * bdf_coeffs[k, 2] + vc = _vec(tmp) + for i in 1:(k - 1) + @.. broadcast=false @views vc -= u_corrector[:, i] * bdf_coeffs[k, i + 2] + end + end + + if mass_matrix === I + nlsolver.tmp = tmp / dt + else + nlsolver.tmp = mass_matrix * tmp / dt + end + β₀ = inv(bdf_coeffs[k, 1]) + α₀ = 1 #bdf_coeffs[k,1] + nlsolver.γ = β₀ + nlsolver.α = α₀ + + nlsolver.method = COEFFICIENT_MULTISTEP + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = z + + for j in 2:k + r[j] = (1 - j) + for i in 2:(k + 1) + r[j] *= ((tdt - j * dt) - ts[i]) / (i * dt) + end + end + + terkp1 = (u - u₀) + for j in 1:(k + 1) + terkp1 *= j * dt / (tdt - ts[j]) + end + + lte = -1 / (1 + k) + for j in 2:k + lte -= bdf_coeffs[k, j] * r[j] + end + lte *= terkp1 + + if integrator.opts.adaptive + for i in 1:(k + 1) + ts_tmp[i + 1] = ts[i] + end + ts_tmp[1] = tdt + atmp = calculate_residuals(_vec(lte), _vec(uprev), _vec(u), integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + + terk = estimate_terk(integrator, cache, k + 1, Val(max_order), u) + fd_weights = calc_finite_difference_weights(ts_tmp, tdt, k, Val(max_order)) + terk = @.. broadcast=false fd_weights[1, k + 1]*u + if u isa Number + for i in 2:(k + 1) + terk += fd_weights[i, k + 1] * u_history[i - 1] + end + terk *= abs(dt^(k)) + else + vc = _vec(terk) + for i in 2:(k + 1) + @.. broadcast=false @views vc += fd_weights[i, k + 1] * u_history[:, i - 1] + end + terk *= abs(dt^(k)) + end + + atmp = calculate_residuals( + _vec(terk), _vec(uprev), _vec(u), integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + cache.terk = integrator.opts.internalnorm(atmp, t) + + if k > 1 + terkm1 = estimate_terk(integrator, cache, k, Val(max_order), u) + atmp = calculate_residuals(_vec(terkm1), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm1 = integrator.opts.internalnorm(atmp, t) + end + if k > 2 + terkm2 = estimate_terk(integrator, cache, k - 1, Val(max_order), u) + atmp = calculate_residuals(_vec(terkm2), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm2 = integrator.opts.internalnorm(atmp, t) + end + if nconsteps > k + 1 && k < max_order + atmp = calculate_residuals(_vec(terkp1), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkp1 = integrator.opts.internalnorm(atmp, t) + else + cache.terkp1 = zero(cache.terk) + end + end + + integrator.fsallast = f(u, p, tdt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::FBDFCache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::FBDFCache{max_order}, + repeat_step = false) where {max_order} + @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, terk_tmp, terkp1_tmp, atmp, tmp, equi_ts, u₀, ts_tmp, step_limiter! = cache + @unpack t, dt, u, f, p, uprev = integrator + + reinitFBDF!(integrator, cache) + k = order + @.. broadcast=false u₀=zero(u) #predictor + tdt = t + dt + if cache.iters_from_event >= 1 + calc_Lagrange_interp!(k, weights, tdt, ts, u_history, u₀) + else + @.. broadcast=false u₀=u + end + markfirststage!(nlsolver) + @.. broadcast=false nlsolver.z=u₀ + mass_matrix = f.mass_matrix + + for i in 1:(k - 1) + equi_ts[i] = t - dt * i + end + + fill!(u_corrector, zero(eltype(u))) + for i in 1:(k - 1) + @views calc_Lagrange_interp!(k, weights, equi_ts[i], ts, u_history, + u_corrector[:, i]) + end + @.. broadcast=false tmp=-uprev * bdf_coeffs[k, 2] + vc = _vec(tmp) + for i in 1:(k - 1) + @.. broadcast=false @views vc -= u_corrector[:, i] * bdf_coeffs[k, i + 2] + end + + invdt = inv(dt) + if mass_matrix === I + @.. broadcast=false nlsolver.tmp=tmp * invdt + else + @.. broadcast=false terkp1_tmp=tmp * invdt + mul!(nlsolver.tmp, mass_matrix, terkp1_tmp) + end + + β₀ = inv(bdf_coeffs[k, 1]) + α₀ = 1 + nlsolver.γ = β₀ + nlsolver.α = α₀ + nlsolver.method = COEFFICIENT_MULTISTEP + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=z + + step_limiter!(u, integrator, p, t + dt) + + #This is to correct the interpolation error of error estimation. + for j in 2:k + r[j] = (1 - j) + for i in 2:(k + 1) + r[j] *= ((tdt - j * dt) - ts[i]) / (i * dt) + end + end + + #for terkp1, we could use corrector and predictor to make an estimation. + @.. broadcast=false terkp1_tmp=(u - u₀) + for j in 1:(k + 1) + @.. broadcast=false terkp1_tmp*=j * dt / (tdt - ts[j]) + end + + lte = -1 / (1 + k) + for j in 2:k + lte -= bdf_coeffs[k, j] * r[j] + end + @.. broadcast=false terk_tmp=lte * terkp1_tmp + if integrator.opts.adaptive + @unpack abstol, reltol, internalnorm = integrator.opts + for i in 1:(k + 1) + ts_tmp[i + 1] = ts[i] + end + ts_tmp[1] = tdt + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, + internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + estimate_terk!(integrator, cache, k + 1, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, + internalnorm, t) + cache.terk = integrator.opts.internalnorm(atmp, t) + + if k > 1 + estimate_terk!(integrator, cache, k, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm1 = integrator.opts.internalnorm(atmp, t) + end + if k > 2 + estimate_terk!(integrator, cache, k - 1, Val(max_order)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkm2 = integrator.opts.internalnorm(atmp, t) + end + if cache.nconsteps > k + 1 && k < max_order + calculate_residuals!(atmp, _vec(terkp1_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + cache.terkp1 = integrator.opts.internalnorm(atmp, t) + else + cache.terkp1 = zero(cache.terkp1) + end + end + + f(integrator.fsallast, u, p, tdt) + integrator.stats.nf += 1 +end diff --git a/src/perform_step/explicit_rk_perform_step.jl b/src/perform_step/explicit_rk_perform_step.jl index e69de29bb2..08ddee112a 100644 --- a/src/perform_step/explicit_rk_perform_step.jl +++ b/src/perform_step/explicit_rk_perform_step.jl @@ -0,0 +1,240 @@ +function initialize!(integrator, cache::ExplicitRKConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::ExplicitRKConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + alg = unwrap_alg(integrator, false) + @unpack A, c, α, αEEst, stages = cache + @unpack kk = cache + + # Calc First + kk[1] = integrator.fsalfirst + + # Calc Middle + for i in 2:(stages - 1) + utilde = zero(kk[1]) + for j in 1:(i - 1) + utilde = utilde + A[j, i] * kk[j] + end + kk[i] = f(uprev + dt * utilde, p, t + c[i] * dt) + integrator.stats.nf += 1 + end + + #Calc Last + utilde_last = zero(kk[1]) + for j in 1:(stages - 1) + utilde_last = utilde_last + A[j, end] * kk[j] + end + u_beforefinal = uprev + dt * utilde_last + kk[end] = f(u_beforefinal, p, t + c[end] * dt) + integrator.stats.nf += 1 + integrator.fsallast = kk[end] # Uses fsallast as temp even if not fsal + + # Accumulate Result + accum = α[1] * kk[1] + for i in 2:stages + accum = accum + α[i] * kk[i] + end + u = uprev + dt * accum + + if integrator.alg isa CompositeAlgorithm + # Hairer II, page 22 modified to use Inf norm + n = maximum(abs.((kk[end] .- kk[end - 1]) / (u .- u_beforefinal))) + integrator.eigen_est = integrator.opts.internalnorm(n, t) + end + + if integrator.opts.adaptive + utilde = αEEst[1] .* kk[1] + for i in 2:stages + utilde = utilde + αEEst[i] * kk[i] + end + atmp = calculate_residuals(dt * utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if !isfsal(alg.tableau) + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + end + + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::ExplicitRKCache) + integrator.kshortsize = 2 + integrator.fsallast = cache.fsallast + integrator.fsalfirst = cache.kk[1] + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@generated function accumulate_explicit_stages!(out, A, uprev, kk, dt, ::Val{s}, + ::Val{r} = Val(s)) where {s, r} + if s == 1 + return :(@muladd @.. broadcast=false out=uprev + dt * kk[1]) + elseif s == 2 + # Note that `A` is transposed + return :(@muladd @.. broadcast=false out=uprev + dt * (A[1, $r] * kk[1])) + else + expr = :(@muladd @.. broadcast=false out=uprev + + dt * (A[1, $r] * kk[1] + A[2, $r] * kk[2])) + acc = expr.args[end].args[end].args[end].args[end].args[end].args + for i in 3:(s - 1) + push!(acc, :(A[$i, $r] * kk[$i])) + end + return expr + end +end + +@generated function accumulate_EEst!(out, αEEst, kk, dt, ::Val{s}) where {s} + if s == 1 + return :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1])) + else + expr = :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1] + αEEst[2] * kk[2])) + acc = expr.args[end].args[end].args[end].args[end].args + for i in 3:s + push!(acc, :(αEEst[$i] * kk[$i])) + end + return expr + end +end + +function accumulate_EEst!(out, αEEst, utilde, kk, dt, stages) + @.. broadcast=false utilde=αEEst[1] * kk[1] + for i in 2:stages + @.. broadcast=false utilde=utilde + αEEst[i] * kk[i] + end + @.. broadcast=false out=dt * utilde +end + +@muladd function compute_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, + stages::Integer) where {F} + # Middle + for i in 2:(stages - 1) + @.. broadcast=false utilde=zero(kk[1][1]) + for j in 1:(i - 1) + @.. broadcast=false utilde=utilde + A[j, i] * kk[j] + end + @.. broadcast=false tmp=uprev + dt * utilde + f(kk[i], tmp, p, t + c[i] * dt) + end + + #Last + @.. broadcast=false utilde=zero(kk[1][1]) + for j in 1:(stages - 1) + @.. broadcast=false utilde=utilde + A[j, end] * kk[j] + end + @.. broadcast=false u=uprev + dt * utilde + f(kk[end], u, p, t + c[end] * dt) #fsallast is tmp even if not fsal + return nothing +end + +@generated function compute_stages!(f::F, A, c, u, tmp, uprev, kk, p, t, dt, + ::Val{s}) where {F, s} + quote + Base.@nexprs $(s - 2) i′->begin + i = i′ + 1 + accumulate_explicit_stages!(tmp, A, uprev, kk, dt, Val(i)) + f(kk[i], tmp, p, t + c[i] * dt) + end + accumulate_explicit_stages!(u, A, uprev, kk, dt, Val(s)) + f(kk[s], u, p, t + c[end] * dt) + end +end + +function runtime_split_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, + stages::Integer) where {F} + Base.@nif 17 (s->(s == stages)) (s->compute_stages!(f, A, c, u, tmp, uprev, kk, p, t, + dt, Val(s))) (s->compute_stages!(f, + A, + c, + utilde, + u, + tmp, + uprev, + kk, + p, + t, + dt, + stages)) +end + +function accumulate_fsal!(u, α, utilde, uprev, kk, dt, stages) + @.. broadcast=false utilde=α[1] * kk[1] + for i in 2:stages + @.. broadcast=false utilde=utilde + α[i] * kk[i] + end + @.. broadcast=false u=uprev + dt * utilde +end + +function runtime_split_fsal!(out, A, utilde, uprev, kk, dt, stages) + Base.@nif 17 (s->(s == stages)) (s->accumulate_explicit_stages!(out, A, uprev, kk, dt, + Val(s + 1), Val(1))) (s->accumulate_fsal!(out, + A, + utilde, + uprev, + kk, + dt, + stages)) +end + +function runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) + Base.@nif 17 (s->(s == stages)) (s->accumulate_EEst!(tmp, αEEst, kk, dt, Val(s))) (s->accumulate_EEst!( + tmp, + αEEst, + utilde, + kk, + dt, + stages)) +end + +@muladd function perform_step!(integrator, cache::ExplicitRKCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + alg = unwrap_alg(integrator, false) + # αEEst is `α - αEEst` + @unpack A, c, α, αEEst, stages = cache.tab + @unpack kk, utilde, tmp, atmp = cache + + runtime_split_stages!(f, A, c, utilde, u, tmp, uprev, kk, p, t, dt, stages) + integrator.stats.nf += stages - 1 + + #Accumulate + if !isfsal(alg.tableau) + runtime_split_fsal!(u, α, utilde, uprev, kk, dt, stages) + end + + if integrator.alg isa CompositeAlgorithm + # Hairer II, page 22 modified to use Inf norm + @.. broadcast=false utilde=abs((kk[end] - kk[end - 1]) / (u - tmp)) + integrator.eigen_est = integrator.opts.internalnorm(norm(utilde, Inf), t) + end + + if integrator.opts.adaptive + runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) + calculate_residuals!(atmp, tmp, uprev, u, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if !isfsal(alg.tableau) + f(integrator.fsallast, u, p, t + dt) + integrator.stats.nf += 1 + end +end diff --git a/src/perform_step/firk_perform_step.jl b/src/perform_step/firk_perform_step.jl new file mode 100644 index 0000000000..f49444eff4 --- /dev/null +++ b/src/perform_step/firk_perform_step.jl @@ -0,0 +1,751 @@ +function do_newJ(integrator, alg, cache, repeat_step)::Bool # for FIRK + integrator.iter <= 1 && return true + repeat_step && return false + first(islinearfunction(integrator)) && return false + integrator.opts.adaptive || return true + alg_can_repeat_jac(alg) || return true + integrator.u_modified && return true + # below is Newton specific logic, so we return non-Newton algs here + alg isa NewtonAlgorithm || return true + nlstatus = cache.status + Int8(nlstatus) < 0 && return true + # no reuse when the cutoff is 0 + fast_convergence_cutoff = alg.fast_convergence_cutoff + iszero(fast_convergence_cutoff) && return true + # reuse J when there is fast convergence + fastconvergence = nlstatus === FastConvergence + return !fastconvergence +end + +function do_newW(integrator, nlsolver, new_jac, W_dt)::Bool # for FIRK + nlsolver === nothing && return true + new_jac && return true + # reuse W when the change in stepsize is small enough + dt = integrator.dt + smallstepchange = abs((dt - W_dt) / W_dt) <= get_new_W_γdt_cutoff(nlsolver) + return !smallstepchange +end + +function initialize!(integrator, cache::RadauIIA3ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + nothing +end + +function initialize!(integrator, cache::RadauIIA5ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + nothing +end + +function initialize!(integrator, cache::RadauIIA3Cache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = cache.k + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + nothing +end + +function initialize!(integrator, cache::RadauIIA5Cache) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = cache.k + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + if integrator.opts.adaptive + @unpack abstol, reltol = integrator.opts + if reltol isa Number + cache.rtol = reltol^(2 / 3) / 10 + cache.atol = cache.rtol * (abstol / reltol) + else + @.. broadcast=false cache.rtol=reltol^(2 / 3) / 10 + @.. broadcast=false cache.atol=cache.rtol * (abstol / reltol) + end + end + nothing +end + +@muladd function perform_step!(integrator, cache::RadauIIA3ConstantCache) + @unpack t, dt, uprev, u, f, p = integrator + @unpack T11, T12, T21, T22, TI11, TI12, TI21, TI22 = cache.tab + @unpack c1, c2, α, β, e1, e2 = cache.tab + @unpack κ, cont1, cont2 = cache + @unpack internalnorm, abstol, reltol, adaptive = integrator.opts + alg = unwrap_alg(integrator, true) + @unpack maxiters = alg + mass_matrix = integrator.f.mass_matrix + + # precalculations + rtol = @. reltol^(2 / 3) / 10 + atol = @. rtol * (abstol / reltol) + αdt, βdt = α / dt, β / dt + J = calc_J(integrator, cache) + + cache.dtprev = one(cache.dtprev) + z1 = w1 = map(zero, u) + z2 = w2 = map(zero, u) + cache.cont1 = map(zero, u) + cache.cont2 = map(zero, u) + + if u isa Number + LU1 = -(αdt + βdt * im) * mass_matrix + J + else + LU1 = lu(-(αdt + βdt * im) * mass_matrix + J) + end + integrator.stats.nw += 1 + + # Newton iteration + local ndw, ff1, ff2 + η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) + fail_convergence = true + iter = 0 + while iter < maxiters + iter += 1 + integrator.stats.nnonliniter += 1 + # evaluate function + ff1 = f(uprev + z1, p, t + c1 * dt) + ff2 = f(uprev + z2, p, t + c2 * dt) + integrator.stats.nf += 2 + + fw1 = @. TI11 * ff1 + TI12 * ff2 + fw2 = @. TI21 * ff1 + TI22 * ff2 + + if mass_matrix isa UniformScaling + Mw1 = @. mass_matrix.λ * w1 + Mw2 = @. mass_matrix.λ * w2 + else + Mw1 = mass_matrix * w1 + Mw2 = mass_matrix * w2 + end + + rhs1 = @. fw1 - αdt * Mw1 + βdt * Mw2 + rhs2 = @. fw2 - βdt * Mw1 - αdt * Mw2 + dw12 = LU1 \ (@. rhs1 + rhs2 * im) + integrator.stats.nsolve += 1 + dw1 = real(dw12) + dw2 = imag(dw12) + + # compute norm of residuals + iter > 1 && (ndwprev = ndw) + atmp1 = calculate_residuals(dw1, uprev, u, atol, rtol, internalnorm, t) + atmp2 = calculate_residuals(dw2, uprev, u, atol, rtol, internalnorm, t) + ndw = internalnorm(atmp1, t) + internalnorm(atmp2, t) + + # check divergence (not in initial step) + if iter > 1 + θ = ndw / ndwprev + (diverge = θ > 1) && (cache.status = Divergence) + (veryslowconvergence = ndw * θ^(maxiters - iter) > κ * (1 - θ)) && + (cache.status = VerySlowConvergence) + if diverge || veryslowconvergence + break + end + end + + w1 = @. w1 - dw1 + w2 = @. w2 - dw2 + + # transform `w` to `z` + z1 = @. T11 * w1 + T12 * w2 + z2 = @. T21 * w1 + T22 * w2 + + # check stopping criterion + iter > 1 && (η = θ / (1 - θ)) + if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) + # Newton method converges + cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : + Convergence + fail_convergence = false + break + end + end + + cache.ηold = η + cache.iter = iter + + u = @. uprev + z2 + + if adaptive + utilde = @. dt * (e1 * ff1 + e2 * ff2) + atmp = calculate_residuals(utilde, uprev, u, atol, rtol, internalnorm, t) + integrator.EEst = internalnorm(atmp, t) + end + + integrator.fsallast = f(u, p, t + dt) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +@muladd function perform_step!(integrator, cache::RadauIIA3Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p, fsallast, fsalfirst = integrator + @unpack T11, T12, T21, T22, TI11, TI12, TI21, TI22 = cache.tab + @unpack c1, c2, α, β, e1, e2 = cache.tab + @unpack κ, cont1, cont2 = cache + @unpack z1, z2, w1, w2, + dw12, cubuff, + k, k2, fw1, fw2, + J, W1, + tmp, atmp, jac_config, rtol, atol, step_limiter! = cache + @unpack internalnorm, abstol, reltol, adaptive = integrator.opts + alg = unwrap_alg(integrator, true) + @unpack maxiters = alg + mass_matrix = integrator.f.mass_matrix + # precalculations + αdt, βdt = α / dt, β / dt + (new_jac = do_newJ(integrator, alg, cache, repeat_step)) && + (calc_J!(J, integrator, cache); cache.W_γdt = dt) + if (new_W = do_newW(integrator, alg, new_jac, cache.W_γdt)) + @inbounds for II in CartesianIndices(J) + W1[II] = -(αdt + βdt * im) * mass_matrix[Tuple(II)...] + J[II] + end + integrator.stats.nw += 1 + end + + #better initial guess + uzero = zero(eltype(z1)) + @. z1 = uzero + @. z2 = uzero + @. w1 = uzero + @. w2 = uzero + @. cache.cont1 = uzero + @. cache.cont2 = uzero + + # Newton iteration + local ndw + η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) + fail_convergence = true + iter = 0 + while iter < maxiters + iter += 1 + integrator.stats.nnonliniter += 1 + # evaluate function + @. tmp = uprev + z1 + f(fsallast, tmp, p, t + c1 * dt) + @. tmp = uprev + z2 + f(k2, tmp, p, t + c2 * dt) + integrator.stats.nf += 2 + + @. fw1 = TI11 * fsallast + TI12 * k2 + @. fw2 = TI21 * fsallast + TI22 * k2 + + if mass_matrix === I + Mw1 = w1 + Mw2 = w2 + elseif mass_matrix isa UniformScaling + mul!(z1, mass_matrix.λ, w1) + mul!(z2, mass_matrix.λ, w2) + Mw1 = z1 + Mw2 = z2 + else + mul!(z1, mass_matrix, w1) + mul!(z2, mass_matrix, w2) + Mw1 = z1 + Mw2 = z2 + end + + @. cubuff = complex(fw1 - αdt * Mw1 + βdt * Mw2, fw2 - βdt * Mw1 - αdt * Mw2) + needfactor = iter == 1 + + linsolve = cache.linsolve + + if needfactor + linres = dolinsolve(integrator, linsolve; A = W1, b = _vec(cubuff), + linu = _vec(dw12)) + else + linres = dolinsolve(integrator, linsolve; A = nothing, b = _vec(cubuff), + linu = _vec(dw12)) + end + + cache.linsolve = linres.cache + + integrator.stats.nsolve += 1 + dw1 = real(dw12) + dw2 = imag(dw12) + + # compute norm of residuals + iter > 1 && (ndwprev = ndw) + calculate_residuals!(atmp, dw1, uprev, u, atol, rtol, internalnorm, t) + ndw1 = internalnorm(atmp, t) + calculate_residuals!(atmp, dw2, uprev, u, atol, rtol, internalnorm, t) + ndw2 = internalnorm(atmp, t) + ndw = ndw1 + ndw2 + + # check divergence (not in initial step) + if iter > 1 + θ = ndw / ndwprev + (diverge = θ > 2) && (cache.status = Divergence) + if diverge + break + end + end + + @. w1 = w1 - dw1 + @. w2 = w2 - dw2 + + # transform `w` to `z` + @. z1 = T11 * w1 + T12 * w2 + @. z2 = T21 * w1 + T22 * w2 + + # check stopping criterion + iter > 1 && (η = θ / (1 - θ)) + if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) + # Newton method converges + cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : + Convergence + fail_convergence = false + break + end + end + if fail_convergence + integrator.force_stepfail = true + integrator.stats.nnonlinconvfail += 1 + return + end + cache.ηold = η + cache.iter = iter + + @. u = uprev + z2 + step_limiter!(u, integrator, p, t + dt) + + if adaptive + utilde = w2 + @. utilde = dt * (e1 * fsallast + e2 * k2) + calculate_residuals!(atmp, utilde, uprev, u, atol, rtol, internalnorm, t) + integrator.EEst = internalnorm(atmp, t) + end + f(fsallast, u, p, t + dt) + integrator.stats.nf += 1 + return +end + +@muladd function perform_step!(integrator, cache::RadauIIA5ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack T11, T12, T13, T21, T22, T23, T31, TI11, TI12, TI13, TI21, TI22, TI23, TI31, TI32, TI33 = cache.tab + @unpack c1, c2, γ, α, β, e1, e2, e3 = cache.tab + @unpack κ, cont1, cont2, cont3 = cache + @unpack internalnorm, abstol, reltol, adaptive = integrator.opts + alg = unwrap_alg(integrator, true) + @unpack maxiters = alg + mass_matrix = integrator.f.mass_matrix + + # precalculations + rtol = @.. broadcast=false reltol^(2 / 3)/10 + atol = @.. broadcast=false rtol*(abstol / reltol) + c1m1 = c1 - 1 + c2m1 = c2 - 1 + c1mc2 = c1 - c2 + γdt, αdt, βdt = γ / dt, α / dt, β / dt + J = calc_J(integrator, cache) + if u isa Number + LU1 = -γdt * mass_matrix + J + LU2 = -(αdt + βdt * im) * mass_matrix + J + else + LU1 = lu(-γdt * mass_matrix + J) + LU2 = lu(-(αdt + βdt * im) * mass_matrix + J) + end + integrator.stats.nw += 1 + + # TODO better initial guess + if integrator.iter == 1 || integrator.u_modified || alg.extrapolant == :constant + cache.dtprev = one(cache.dtprev) + z1 = w1 = map(zero, u) + z2 = w2 = map(zero, u) + z3 = w3 = map(zero, u) + cache.cont1 = map(zero, u) + cache.cont2 = map(zero, u) + cache.cont3 = map(zero, u) + else + c3′ = dt / cache.dtprev + c1′ = c1 * c3′ + c2′ = c2 * c3′ + z1 = @.. broadcast=false c1′*(cont1 + (c1′ - c2m1) * (cont2 + (c1′ - c1m1) * cont3)) + z2 = @.. broadcast=false c2′*(cont1 + (c2′ - c2m1) * (cont2 + (c2′ - c1m1) * cont3)) + z3 = @.. broadcast=false c3′*(cont1 + (c3′ - c2m1) * (cont2 + (c3′ - c1m1) * cont3)) + w1 = @.. broadcast=false TI11*z1+TI12*z2+TI13*z3 + w2 = @.. broadcast=false TI21*z1+TI22*z2+TI23*z3 + w3 = @.. broadcast=false TI31*z1+TI32*z2+TI33*z3 + end + + # Newton iteration + local ndw + η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) + fail_convergence = true + iter = 0 + while iter < maxiters + iter += 1 + integrator.stats.nnonliniter += 1 + + # evaluate function + ff1 = f(uprev + z1, p, t + c1 * dt) + ff2 = f(uprev + z2, p, t + c2 * dt) + ff3 = f(uprev + z3, p, t + dt) # c3 = 1 + integrator.stats.nf += 3 + + fw1 = @.. broadcast=false TI11*ff1+TI12*ff2+TI13*ff3 + fw2 = @.. broadcast=false TI21*ff1+TI22*ff2+TI23*ff3 + fw3 = @.. broadcast=false TI31*ff1+TI32*ff2+TI33*ff3 + + if mass_matrix isa UniformScaling # `UniformScaling` doesn't play nicely with broadcast + Mw1 = @.. broadcast=false mass_matrix.λ*w1 + Mw2 = @.. broadcast=false mass_matrix.λ*w2 + Mw3 = @.. broadcast=false mass_matrix.λ*w3 + else + Mw1 = mass_matrix * w1 + Mw2 = mass_matrix * w2 + Mw3 = mass_matrix * w3 + end + + rhs1 = @.. broadcast=false fw1-γdt * Mw1 + rhs2 = @.. broadcast=false fw2 - αdt * Mw2+βdt * Mw3 + rhs3 = @.. broadcast=false fw3 - βdt * Mw2-αdt * Mw3 + dw1 = LU1 \ rhs1 + dw23 = LU2 \ (@.. broadcast=false rhs2+rhs3 * im) + integrator.stats.nsolve += 2 + dw2 = real(dw23) + dw3 = imag(dw23) + + # compute norm of residuals + iter > 1 && (ndwprev = ndw) + atmp1 = calculate_residuals(dw1, uprev, u, atol, rtol, internalnorm, t) + atmp2 = calculate_residuals(dw2, uprev, u, atol, rtol, internalnorm, t) + atmp3 = calculate_residuals(dw3, uprev, u, atol, rtol, internalnorm, t) + ndw = internalnorm(atmp1, t) + internalnorm(atmp2, t) + internalnorm(atmp3, t) + + # check divergence (not in initial step) + if iter > 1 + θ = ndw / ndwprev + (diverge = θ > 1) && (cache.status = Divergence) + (veryslowconvergence = ndw * θ^(maxiters - iter) > κ * (1 - θ)) && + (cache.status = VerySlowConvergence) + if diverge || veryslowconvergence + break + end + end + + w1 = @.. broadcast=false w1-dw1 + w2 = @.. broadcast=false w2-dw2 + w3 = @.. broadcast=false w3-dw3 + + # transform `w` to `z` + z1 = @.. broadcast=false T11*w1+T12*w2+T13*w3 + z2 = @.. broadcast=false T21*w1+T22*w2+T23*w3 + z3 = @.. broadcast=false T31 * w1+w2 # T32 = 1, T33 = 0 + + # check stopping criterion + iter > 1 && (η = θ / (1 - θ)) + if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) + # Newton method converges + cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : + Convergence + fail_convergence = false + break + end + end + if fail_convergence + integrator.force_stepfail = true + integrator.stats.nnonlinconvfail += 1 + return + end + cache.ηold = η + cache.iter = iter + + u = @.. broadcast=false uprev+z3 + + if adaptive + e1dt, e2dt, e3dt = e1 / dt, e2 / dt, e3 / dt + tmp = @.. broadcast=false e1dt*z1+e2dt*z2+e3dt*z3 + mass_matrix != I && (tmp = mass_matrix * tmp) + utilde = @.. broadcast=false integrator.fsalfirst+tmp + alg.smooth_est && (utilde = LU1 \ utilde; integrator.stats.nsolve += 1) + # RadauIIA5 needs a transformed rtol and atol see + # https://github.com/luchr/ODEInterface.jl/blob/0bd134a5a358c4bc13e0fb6a90e27e4ee79e0115/src/radau5.f#L399-L421 + atmp = calculate_residuals(utilde, uprev, u, atol, rtol, internalnorm, t) + integrator.EEst = internalnorm(atmp, t) + + if !(integrator.EEst < oneunit(integrator.EEst)) && integrator.iter == 1 || + integrator.u_modified + f0 = f(uprev .+ utilde, p, t) + integrator.stats.nf += 1 + utilde = @.. broadcast=false f0+tmp + alg.smooth_est && (utilde = LU1 \ utilde; integrator.stats.nsolve += 1) + atmp = calculate_residuals(utilde, uprev, u, atol, rtol, internalnorm, t) + integrator.EEst = internalnorm(atmp, t) + end + end + + if integrator.EEst <= oneunit(integrator.EEst) + cache.dtprev = dt + if alg.extrapolant != :constant + cache.cont1 = @.. broadcast=false (z2 - z3)/c2m1 + tmp = @.. broadcast=false (z1 - z2)/c1mc2 + cache.cont2 = @.. broadcast=false (tmp - cache.cont1)/c1m1 + cache.cont3 = @.. broadcast=false cache.cont2-(tmp - z1 / c1) / c2 + end + end + + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +@muladd function perform_step!(integrator, cache::RadauIIA5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p, fsallast, fsalfirst = integrator + @unpack T11, T12, T13, T21, T22, T23, T31, TI11, TI12, TI13, TI21, TI22, TI23, TI31, TI32, TI33 = cache.tab + @unpack c1, c2, γ, α, β, e1, e2, e3 = cache.tab + @unpack κ, cont1, cont2, cont3 = cache + @unpack z1, z2, z3, w1, w2, w3, + dw1, ubuff, dw23, cubuff, + k, k2, k3, fw1, fw2, fw3, + J, W1, W2, + tmp, atmp, jac_config, linsolve1, linsolve2, rtol, atol, step_limiter! = cache + @unpack internalnorm, abstol, reltol, adaptive = integrator.opts + alg = unwrap_alg(integrator, true) + @unpack maxiters = alg + mass_matrix = integrator.f.mass_matrix + + # precalculations + c1m1 = c1 - 1 + c2m1 = c2 - 1 + c1mc2 = c1 - c2 + γdt, αdt, βdt = γ / dt, α / dt, β / dt + (new_jac = do_newJ(integrator, alg, cache, repeat_step)) && + (calc_J!(J, integrator, cache); cache.W_γdt = dt) + if (new_W = do_newW(integrator, alg, new_jac, cache.W_γdt)) + @inbounds for II in CartesianIndices(J) + W1[II] = -γdt * mass_matrix[Tuple(II)...] + J[II] + W2[II] = -(αdt + βdt * im) * mass_matrix[Tuple(II)...] + J[II] + end + integrator.stats.nw += 1 + end + + # TODO better initial guess + if integrator.iter == 1 || integrator.u_modified || alg.extrapolant == :constant + cache.dtprev = one(cache.dtprev) + uzero = zero(eltype(u)) + @.. broadcast=false z1=uzero + @.. broadcast=false z2=uzero + @.. broadcast=false z3=uzero + @.. broadcast=false w1=uzero + @.. broadcast=false w2=uzero + @.. broadcast=false w3=uzero + @.. broadcast=false cache.cont1=uzero + @.. broadcast=false cache.cont2=uzero + @.. broadcast=false cache.cont3=uzero + else + c3′ = dt / cache.dtprev + c1′ = c1 * c3′ + c2′ = c2 * c3′ + @.. broadcast=false z1=c1′ * (cont1 + (c1′ - c2m1) * (cont2 + (c1′ - c1m1) * cont3)) + @.. broadcast=false z2=c2′ * (cont1 + (c2′ - c2m1) * (cont2 + (c2′ - c1m1) * cont3)) + @.. broadcast=false z3=c3′ * (cont1 + (c3′ - c2m1) * (cont2 + (c3′ - c1m1) * cont3)) + @.. broadcast=false w1=TI11 * z1 + TI12 * z2 + TI13 * z3 + @.. broadcast=false w2=TI21 * z1 + TI22 * z2 + TI23 * z3 + @.. broadcast=false w3=TI31 * z1 + TI32 * z2 + TI33 * z3 + end + + # Newton iteration + local ndw + η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) + fail_convergence = true + iter = 0 + while iter < maxiters + iter += 1 + integrator.stats.nnonliniter += 1 + + # evaluate function + @.. broadcast=false tmp=uprev + z1 + f(fsallast, tmp, p, t + c1 * dt) + @.. broadcast=false tmp=uprev + z2 + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false tmp=uprev + z3 + f(k3, tmp, p, t + dt) # c3 = 1 + integrator.stats.nf += 3 + + @.. broadcast=false fw1=TI11 * fsallast + TI12 * k2 + TI13 * k3 + @.. broadcast=false fw2=TI21 * fsallast + TI22 * k2 + TI23 * k3 + @.. broadcast=false fw3=TI31 * fsallast + TI32 * k2 + TI33 * k3 + + if mass_matrix === I + Mw1 = w1 + Mw2 = w2 + Mw3 = w3 + elseif mass_matrix isa UniformScaling + mul!(z1, mass_matrix.λ, w1) + mul!(z2, mass_matrix.λ, w2) + mul!(z3, mass_matrix.λ, w3) + Mw1 = z1 + Mw2 = z2 + Mw3 = z3 + else + mul!(z1, mass_matrix, w1) + mul!(z2, mass_matrix, w2) + mul!(z3, mass_matrix, w3) + Mw1 = z1 + Mw2 = z2 + Mw3 = z3 + end + + @.. broadcast=false ubuff=fw1 - γdt * Mw1 + needfactor = iter == 1 && new_W + + linsolve1 = cache.linsolve1 + + if needfactor + linres1 = dolinsolve(integrator, linsolve1; A = W1, b = _vec(ubuff), + linu = _vec(dw1)) + else + linres1 = dolinsolve(integrator, linsolve1; A = nothing, b = _vec(ubuff), + linu = _vec(dw1)) + end + + cache.linsolve1 = linres1.cache + + @.. broadcast=false cubuff=complex(fw2 - αdt * Mw2 + βdt * Mw3, + fw3 - βdt * Mw2 - αdt * Mw3) + + linsolve2 = cache.linsolve2 + + if needfactor + linres2 = dolinsolve(integrator, linsolve2; A = W2, b = _vec(cubuff), + linu = _vec(dw23)) + else + linres2 = dolinsolve(integrator, linsolve2; A = nothing, b = _vec(cubuff), + linu = _vec(dw23)) + end + + cache.linsolve2 = linres2.cache + + integrator.stats.nsolve += 2 + dw2 = z2 + dw3 = z3 + @.. broadcast=false dw2=real(dw23) + @.. broadcast=false dw3=imag(dw23) + + # compute norm of residuals + iter > 1 && (ndwprev = ndw) + calculate_residuals!(atmp, dw1, uprev, u, atol, rtol, internalnorm, t) + ndw1 = internalnorm(atmp, t) + calculate_residuals!(atmp, dw2, uprev, u, atol, rtol, internalnorm, t) + ndw2 = internalnorm(atmp, t) + calculate_residuals!(atmp, dw3, uprev, u, atol, rtol, internalnorm, t) + ndw3 = internalnorm(atmp, t) + ndw = ndw1 + ndw2 + ndw3 + + # check divergence (not in initial step) + if iter > 1 + θ = ndw / ndwprev + (diverge = θ > 1) && (cache.status = Divergence) + (veryslowconvergence = ndw * θ^(maxiters - iter) > κ * (1 - θ)) && + (cache.status = VerySlowConvergence) + if diverge || veryslowconvergence + break + end + end + + @.. broadcast=false w1=w1 - dw1 + @.. broadcast=false w2=w2 - dw2 + @.. broadcast=false w3=w3 - dw3 + + # transform `w` to `z` + @.. broadcast=false z1=T11 * w1 + T12 * w2 + T13 * w3 + @.. broadcast=false z2=T21 * w1 + T22 * w2 + T23 * w3 + @.. broadcast=false z3=T31 * w1 + w2 # T32 = 1, T33 = 0 + + # check stopping criterion + iter > 1 && (η = θ / (1 - θ)) + if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) + # Newton method converges + cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : + Convergence + fail_convergence = false + break + end + end + if fail_convergence + integrator.force_stepfail = true + integrator.stats.nnonlinconvfail += 1 + return + end + cache.ηold = η + cache.iter = iter + + @.. broadcast=false u=uprev + z3 + step_limiter!(u, integrator, p, t + dt) + + if adaptive + utilde = w2 + e1dt, e2dt, e3dt = e1 / dt, e2 / dt, e3 / dt + @.. broadcast=false tmp=e1dt * z1 + e2dt * z2 + e3dt * z3 + mass_matrix != I && (mul!(w1, mass_matrix, tmp); copyto!(tmp, w1)) + @.. broadcast=false ubuff=integrator.fsalfirst + tmp + + if alg.smooth_est + linres1 = dolinsolve(integrator, linres1.cache; b = _vec(ubuff), + linu = _vec(utilde)) + cache.linsolve1 = linres1.cache + integrator.stats.nsolve += 1 + end + + # RadauIIA5 needs a transformed rtol and atol see + # https://github.com/luchr/ODEInterface.jl/blob/0bd134a5a358c4bc13e0fb6a90e27e4ee79e0115/src/radau5.f#L399-L421 + calculate_residuals!(atmp, utilde, uprev, u, atol, rtol, internalnorm, t) + integrator.EEst = internalnorm(atmp, t) + + if !(integrator.EEst < oneunit(integrator.EEst)) && integrator.iter == 1 || + integrator.u_modified + @.. broadcast=false utilde=uprev + utilde + f(fsallast, utilde, p, t) + integrator.stats.nf += 1 + @.. broadcast=false ubuff=fsallast + tmp + + if alg.smooth_est + linres1 = dolinsolve(integrator, linres1.cache; b = _vec(ubuff), + linu = _vec(utilde)) + cache.linsolve1 = linres1.cache + integrator.stats.nsolve += 1 + end + + calculate_residuals!(atmp, utilde, uprev, u, atol, rtol, internalnorm, t) + integrator.EEst = internalnorm(atmp, t) + end + end + + if integrator.EEst <= oneunit(integrator.EEst) + cache.dtprev = dt + if alg.extrapolant != :constant + @.. broadcast=false cache.cont1=(z2 - z3) / c2m1 + @.. broadcast=false tmp=(z1 - z2) / c1mc2 + @.. broadcast=false cache.cont2=(tmp - cache.cont1) / c1m1 + @.. broadcast=false cache.cont3=cache.cont2 - (tmp - z1 / c1) / c2 + end + end + f(fsallast, u, p, t + dt) + integrator.stats.nf += 1 + return +end diff --git a/src/perform_step/fixed_timestep_perform_step.jl b/src/perform_step/fixed_timestep_perform_step.jl index 2923459c72..643ce748f8 100644 --- a/src/perform_step/fixed_timestep_perform_step.jl +++ b/src/perform_step/fixed_timestep_perform_step.jl @@ -40,4 +40,492 @@ function perform_step!(integrator, cache::FunctionMapCache, repeat_step = false) end integrator.stats.nf += 1 end -end \ No newline at end of file +end + +function initialize!(integrator, cache::EulerConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::EulerConstantCache, repeat_step = false) + @unpack t, dt, uprev, f, p = integrator + @muladd u = @.. broadcast=false uprev+dt * integrator.fsalfirst + k = f(u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 + integrator.fsallast = k + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::EulerCache) + integrator.kshortsize = 2 + @unpack k, fsalfirst = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::EulerCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @muladd @.. broadcast=false u=uprev + dt * integrator.fsalfirst + f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function initialize!(integrator, cache::Union{HeunConstantCache, RalstonConstantCache}) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, + cache::Union{HeunConstantCache, RalstonConstantCache}, + repeat_step = false) + @unpack t, dt, uprev, u, f, p, fsalfirst = integrator + + # precalculations + if cache isa HeunConstantCache + a₁ = dt + a₂ = dt / 2 + else # Ralston + a₁ = 2 * dt / 3 + a₂ = dt / 4 + a₃ = 3 * a₂ + end + + tmp = @.. broadcast=false uprev+a₁ * fsalfirst + k2 = f(tmp, p, t + a₁) + integrator.stats.nf += 1 + + if cache isa HeunConstantCache + u = @.. broadcast=false uprev+a₂ * (fsalfirst + k2) + else + u = @.. broadcast=false uprev+a₂*fsalfirst+a₃*k2 + end + + if integrator.opts.adaptive + if cache isa HeunConstantCache + tmp = @.. broadcast=false a₂*(k2 - fsalfirst) + else + tmp = @.. broadcast=false a₃*(k2 - fsalfirst) + end + + atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + k = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.fsallast = k + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::Union{HeunCache, RalstonCache}) + integrator.kshortsize = 2 + @unpack k, fsalfirst = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::Union{HeunCache, RalstonCache}, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack fsalfirst, k, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + + # precalculations + if cache isa HeunCache + a₁ = dt + a₂ = dt / 2 + else # Ralston + a₁ = 2 * dt / 3 + a₂ = dt / 4 + a₃ = 3 * a₂ + end + + @.. broadcast=false thread=thread tmp=uprev + a₁ * fsalfirst + stage_limiter!(tmp, integrator, p, t + a₁) + f(k, tmp, p, t + a₁) + integrator.stats.nf += 1 + + if cache isa HeunCache + @.. broadcast=false thread=thread u=uprev + a₂ * (fsalfirst + k) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + else + @.. broadcast=false thread=thread u=uprev + a₂ * fsalfirst + a₃ * k + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + end + + if integrator.opts.adaptive + if cache isa HeunCache + @.. broadcast=false thread=thread tmp=a₂ * (k - fsalfirst) + else + @.. broadcast=false thread=thread tmp=a₃ * (k - fsalfirst) + end + + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +function initialize!(integrator, cache::MidpointConstantCache) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::MidpointConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + halfdt = dt / 2 + tmp = @.. broadcast=false uprev+halfdt * integrator.fsalfirst + k = f(tmp, p, t + halfdt) + integrator.stats.nf += 1 + u = @.. broadcast=false uprev+dt * k + integrator.fsallast = f(u, p, t + dt) # For interpolation, then FSAL'd + integrator.stats.nf += 1 + if integrator.opts.adaptive + utilde = @.. broadcast=false dt*(integrator.fsalfirst - k) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::MidpointCache) + @unpack k, fsalfirst = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # FSAL for interpolation + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::MidpointCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tmp, k, fsalfirst, atmp, stage_limiter!, step_limiter!, thread = cache + halfdt = dt / 2 + @.. broadcast=false thread=thread tmp=uprev + halfdt * fsalfirst + stage_limiter!(k, tmp, p, t + halfdt) + f(k, tmp, p, t + halfdt) + integrator.stats.nf += 1 + @.. broadcast=false thread=thread u=uprev + dt * k + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + if integrator.opts.adaptive + @.. broadcast=false thread=thread tmp=dt * (fsalfirst - k) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + f(k, u, p, t + dt) + integrator.stats.nf += 1 +end + +function initialize!(integrator, cache::RK4ConstantCache) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::RK4ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + halfdt = dt / 2 + k₁ = integrator.fsalfirst + ttmp = t + halfdt + k₂ = f(uprev + halfdt * k₁, p, ttmp) + k₃ = f(uprev + halfdt * k₂, p, ttmp) + k₄ = f(uprev + dt * k₃, p, t + dt) + u = uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 4 + if integrator.opts.adaptive + # Shampine Solving ODEs and DDEs with Residual Control Estimate + k₅ = integrator.fsallast + + # one(t) so that types are correct but unitless + σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 + σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 + p1 = (1 - σ₁) * uprev + σ₁ * u + + σ₁ * (σ₁ - 1) * ((1 - 2σ₁) * (u - uprev) + (σ₁ - 1) * dt * k₁ + σ₁ * dt * k₅) + p2 = (1 - σ₂) * uprev + σ₂ * u + + σ₂ * (σ₂ - 1) * ((1 - 2σ₂) * (u - uprev) + (σ₂ - 1) * dt * k₁ + σ₂ * dt * k₅) + pprime1 = k₁ + + σ₁ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₁ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt + pprime2 = k₁ + + σ₂ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₂ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt + e1 = integrator.opts.internalnorm( + calculate_residuals(dt * (f(p1, p, t + σ₁ * dt) - + pprime1), uprev, u, + integrator.opts.abstol, + integrator.opts.reltol, + integrator.opts.internalnorm, + t), + t) + e2 = integrator.opts.internalnorm( + calculate_residuals(dt * (f(p2, p, t + σ₂ * dt) - + pprime2), uprev, u, + integrator.opts.abstol, + integrator.opts.reltol, + integrator.opts.internalnorm, + t), + t) + integrator.stats.nf += 2 + integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) + end + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::RK4Cache) + @unpack tmp, fsalfirst, k₂, k₃, k₄, k = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # pre-start FSAL + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::RK4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tmp, fsalfirst, k₂, k₃, k₄, k, atmp, stage_limiter!, step_limiter!, thread = cache + k₁ = fsalfirst + halfdt = dt / 2 + ttmp = t + halfdt + @.. broadcast=false thread=thread tmp=uprev + halfdt * k₁ + stage_limiter!(tmp, integrator, p, ttmp) + f(k₂, tmp, p, ttmp) + @.. broadcast=false thread=thread tmp=uprev + halfdt * k₂ + stage_limiter!(tmp, integrator, p, ttmp) + f(k₃, tmp, p, ttmp) + @.. broadcast=false thread=thread tmp=uprev + dt * k₃ + stage_limiter!(tmp, integrator, p, t + dt) + f(k₄, tmp, p, t + dt) + @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k, u, p, t + dt) + integrator.stats.nf += 4 + if integrator.opts.adaptive + # Shampine Solving ODEs and DDEs with Residual Control Estimate + k₅ = k + _p = k₂ + pprime = k₃ # Alias some cache arrays + # one(t) so that types are correct but unitless + σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 + σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 + @.. broadcast=false thread=thread tmp=(1 - σ₁) * uprev + σ₁ * u + + σ₁ * (σ₁ - 1) * + ((1 - 2σ₁) * (u - uprev) + + (σ₁ - 1) * dt * k₁ + + σ₁ * dt * k₅) + @.. broadcast=false thread=thread pprime=k₁ + + σ₁ * + (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₁ * + (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - + 6 * u) + + 6 * u) / dt + f(_p, tmp, p, t + σ₁ * dt) + @.. broadcast=false thread=thread tmp=dt * (_p - pprime) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + e1 = integrator.opts.internalnorm(atmp, t) + @.. broadcast=false thread=thread tmp=(1 - σ₂) * uprev + σ₂ * u + + σ₂ * (σ₂ - 1) * + ((1 - 2σ₂) * (u - uprev) + + (σ₂ - 1) * dt * k₁ + + σ₂ * dt * k₅) + @.. broadcast=false thread=thread pprime=k₁ + + σ₂ * + (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + + σ₂ * + (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - + 6 * u) + + 6 * u) / dt + f(_p, tmp, p, t + σ₂ * dt) + @.. broadcast=false thread=thread tmp=dt * (_p - pprime) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + e2 = integrator.opts.internalnorm(atmp, t) + integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) + integrator.stats.nf += 2 + end +end + +function initialize!(integrator, cache::Anas5ConstantCache) + integrator.kshortsize = 7 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::Anas5ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache + ## Note that c1 and b2 were 0. + alg = unwrap_alg(integrator, false) + w = alg.w + v = w * dt + ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. + a65 = (-8000 // 1071) * + (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + + 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) + a61 += (-119 // 200) * a65 + a63 += (189 // 100) * a65 + a64 += (-459 // 200) * a65 + k1 = integrator.fsalfirst + k2 = f(uprev + dt * a21 * k1, p, t + c2 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c3 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + 2 * k3), p, t + c4 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c5 * dt) + k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, + t + c6 * dt) + u = uprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) + k7 = f(u, p, t + dt) + integrator.fsallast = k7 + integrator.stats.nf += 6 + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.u = u +end + +function initialize!(integrator, cache::Anas5Cache) + integrator.kshortsize = 7 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k7 # setup pointers + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::Anas5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + uidx = eachindex(integrator.uprev) + @unpack k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache.tab + alg = unwrap_alg(integrator, false) + w = alg.w + v = w * dt + ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. + a65 = (-8000 // 1071) * + (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + + 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) + a61 += (-119 // 200) * a65 + a63 += (189 // 100) * a65 + a64 += (-459 // 200) * a65 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + a21 * k1[i] + end + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + dt * (a31 * k1[i] + a32 * k2[i]) + end + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + dt * (a41 * k1[i] + a42 * k2[i] + 2 * k3[i]) + end + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + + dt * (a51 * k1[i] + a52 * k2[i] + a53 * k3[i] + a54 * k4[i]) + end + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i] + + dt * (a61 * k1[i] + a62 * k2[i] + a63 * k3[i] + a64 * k4[i] + + a65 * k5[i]) + end + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @tight_loop_macros for i in uidx + @inbounds u[i] = uprev[i] + + dt * + (b1 * k1[i] + b3 * k3[i] + b4 * k4[i] + b5 * k5[i] + b6 * k6[i]) + end + stage_limiter!(tmp, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k7, u, p, t + dt) + integrator.stats.nf += 6 +end diff --git a/src/perform_step/high_order_rk_perform_step.jl b/src/perform_step/high_order_rk_perform_step.jl new file mode 100644 index 0000000000..62e6025575 --- /dev/null +++ b/src/perform_step/high_order_rk_perform_step.jl @@ -0,0 +1,1153 @@ +function initialize!(integrator, cache::TanYam7ConstantCache) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::TanYam7ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10 = cache + k1 = integrator.fsalfirst + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a43 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4), p, t + c4 * dt) + k6 = f(uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5), p, t + c5 * dt) + k7 = f(uprev + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), p, + t + c6 * dt) + k8 = f(uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7), + p, t + c7 * dt) + k9 = f( + uprev + + dt * + (a91 * k1 + a93 * k3 + a94 * k4 + a95 * k5 + a96 * k6 + a97 * k7 + a98 * k8), + p, + t + dt) + k10 = f( + uprev + + dt * (a101 * k1 + a103 * k3 + a104 * k4 + a105 * k5 + a106 * k6 + a107 * k7 + + a108 * k8), + p, + t + dt) + integrator.stats.nf += 9 + u = uprev + dt * (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9) + if integrator.opts.adaptive + utilde = dt * + (btilde1 * k1 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + btilde7 * k7 + + btilde8 * k8 + btilde9 * k9 + btilde10 * k10) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.fsallast = f(u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::TanYam7Cache) + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = cache.k + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::TanYam7Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack fsalfirst, k2, k3, k4, k5, k6, k7, k8, k9, k10, utilde, tmp, atmp, k, stage_limiter!, step_limiter!, thread = cache + @unpack c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10 = cache.tab + k1 = fsalfirst + f(k1, uprev, p, t) + a = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k6, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + + a76 * k6) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k7, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + + a86 * k6 + + a87 * k7) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k8, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a91 * k1 + a93 * k3 + a94 * k4 + a95 * k5 + + a96 * k6 + + a97 * k7 + a98 * k8) + stage_limiter!(tmp, integrator, p, t + dt) + f(k9, tmp, p, t + dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * + (a101 * k1 + a103 * k3 + a104 * k4 + a105 * k5 + + a106 * k6 + + a107 * k7 + a108 * k8) + stage_limiter!(tmp, integrator, p, t + dt) + f(k10, tmp, p, t + dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + + b8 * k8 + + b9 * k9) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + integrator.stats.nf += 10 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde4 * k4 + + btilde5 * k5 + + btilde6 * k6 + btilde7 * k7 + + btilde8 * k8 + + btilde9 * k9 + btilde10 * k10) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + f(k, u, p, t + dt) + integrator.stats.nf += 1 + return nothing +end + +#= +@muladd function perform_step!(integrator, cache::TanYam7Cache, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + uidx = eachindex(integrator.uprev) + @unpack fsalfirst,k2,k3,k4,k5,k6,k7,k8,k9,k10,utilde,tmp,atmp,k = cache + @unpack c1,c2,c3,c4,c5,c6,c7,a21,a31,a32,a41,a43,a51,a53,a54,a61,a63,a64,a65,a71,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,a91,a93,a94,a95,a96,a97,a98,a101,a103,a104,a105,a106,a107,a108,b1,b4,b5,b6,b7,b8,b9,btilde1,btilde4,btilde5,btilde6,btilde7,btilde8,btilde9,btilde10 = cache.tab + k1 = fsalfirst + f(k1, uprev, p, t) + a = dt*a21 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2, tmp, p, t + c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3, tmp, p, t + c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a43*k3[i]) + end + f(k4, tmp, p, t + c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a53*k3[i]+a54*k4[i]) + end + f(k5, tmp, p, t + c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6, tmp, p, t + c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) + end + f(k7, tmp, p, t + c6*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) + end + f(k8, tmp, p, t + c7*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a91*k1[i]+a93*k3[i]+a94*k4[i]+a95*k5[i]+a96*k6[i]+a97*k7[i]+a98*k8[i]) + end + f(k9, tmp, p, t+dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a101*k1[i]+a103*k3[i]+a104*k4[i]+a105*k5[i]+a106*k6[i]+a107*k7[i]+a108*k8[i]) + end + f(k10, tmp, p, t+dt) + @tight_loop_macros for i in uidx + @inbounds u[i] = uprev[i] + dt*(b1*k1[i]+b4*k4[i]+b5*k5[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]) + end + integrator.stats.nf += 10 + if integrator.opts.adaptive + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(btilde1*k1[i]+btilde4*k4[i]+btilde5*k5[i]+btilde6*k6[i]+btilde7*k7[i]+btilde8*k8[i]+btilde9*k9[i]+btilde10*k10[i]) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + integrator.EEst = integrator.opts.internalnorm(atmp,t) + end + f(k, u, p, t+dt) + integrator.stats.nf += 1 +end +=# + +function initialize!(integrator, cache::DP8ConstantCache) + integrator.kshortsize = 7 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + @inbounds for i in eachindex(integrator.k) + integrator.k[i] = zero(integrator.fsalfirst) + end +end + +@muladd function perform_step!(integrator, cache::DP8ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache + k1 = integrator.fsalfirst + a = dt * a0201 + k2 = f(uprev + a * k1, p, t + c2 * dt) + k3 = f(uprev + dt * (a0301 * k1 + a0302 * k2), p, t + c3 * dt) + k4 = f(uprev + dt * (a0401 * k1 + a0403 * k3), p, t + c4 * dt) + k5 = f(uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4), p, t + c5 * dt) + k6 = f(uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5), p, t + c6 * dt) + k7 = f(uprev + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6), p, t + c7 * dt) + k8 = f( + uprev + dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + a0807 * k7), p, + t + c8 * dt) + k9 = f( + uprev + + dt * + (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + a0907 * k7 + a0908 * k8), + p, + t + c9 * dt) + k10 = f( + uprev + + dt * + (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + a1007 * k7 + a1008 * k8 + + a1009 * k9), + p, + t + c10 * dt) + k11 = f( + uprev + + dt * + (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + a1107 * k7 + a1108 * k8 + + a1109 * k9 + a1110 * k10), + p, + t + c11 * dt) + k12 = f( + uprev + + dt * + (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + a1207 * k7 + a1208 * k8 + + a1209 * k9 + a1210 * k10 + a1211 * k11), + p, + t + dt) + integrator.stats.nf += 11 + kupdate = b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + b10 * k10 + b11 * k11 + + b12 * k12 + u = uprev + dt * kupdate + if integrator.opts.adaptive + utilde = dt * (k1 * er1 + k6 * er6 + k7 * er7 + k8 * er8 + k9 * er9 + k10 * er10 + + k11 * er11 + k12 * er12) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + err5 = integrator.opts.internalnorm(atmp, t) # Order 5 + utilde = dt * + (btilde1 * k1 + btilde6 * k6 + btilde7 * k7 + btilde8 * k8 + btilde9 * k9 + + btilde10 * k10 + btilde11 * k11 + btilde12 * k12) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + err3 = integrator.opts.internalnorm(atmp, t) # Order 3 + err52 = err5 * err5 + if err5 ≈ 0 && err3 ≈ 0 + integrator.EEst = zero(integrator.EEst) + else + integrator.EEst = err52 / sqrt(err52 + 0.01 * err3 * err3) + end + end + k13 = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.fsallast = k13 + if integrator.opts.calck + @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache + @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache + k14 = f( + uprev + + dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + a1409 * k9 + a1410 * k10 + + a1411 * k11 + a1412 * k12 + a1413 * k13), + p, + t + c14 * dt) + k15 = f( + uprev + + dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + a1508 * k8 + a1511 * k11 + + a1512 * k12 + a1513 * k13 + a1514 * k14), + p, + t + c15 * dt) + k16 = f( + uprev + + dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + a1608 * k8 + a1609 * k9 + + a1613 * k13 + a1614 * k14 + a1615 * k15), + p, + t + c16 * dt) + integrator.stats.nf += 3 + udiff = kupdate + integrator.k[1] = udiff + bspl = k1 - udiff + integrator.k[2] = bspl + integrator.k[3] = udiff - k13 - bspl + integrator.k[4] = d401 * k1 + d406 * k6 + d407 * k7 + d408 * k8 + d409 * k9 + + d410 * k10 + d411 * k11 + d412 * k12 + d413 * k13 + d414 * k14 + + d415 * k15 + d416 * k16 + integrator.k[5] = d501 * k1 + d506 * k6 + d507 * k7 + d508 * k8 + d509 * k9 + + d510 * k10 + d511 * k11 + d512 * k12 + d513 * k13 + d514 * k14 + + d515 * k15 + d516 * k16 + integrator.k[6] = d601 * k1 + d606 * k6 + d607 * k7 + d608 * k8 + d609 * k9 + + d610 * k10 + d611 * k11 + d612 * k12 + d613 * k13 + d614 * k14 + + d615 * k15 + d616 * k16 + integrator.k[7] = d701 * k1 + d706 * k6 + d707 * k7 + d708 * k8 + d709 * k9 + + d710 * k10 + d711 * k11 + d712 * k12 + d713 * k13 + d714 * k14 + + d715 * k15 + d716 * k16 + end + integrator.u = u +end + +function initialize!(integrator, cache::DP8Cache) + integrator.kshortsize = 7 + resize!(integrator.k, integrator.kshortsize) + integrator.k .= [ + cache.udiff, + cache.bspl, + cache.dense_tmp3, + cache.dense_tmp4, + cache.dense_tmp5, + cache.dense_tmp6, + cache.dense_tmp7 + ] + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k13 + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::DP8Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + uidx = eachindex(integrator.uprev) + @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache.tab + @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, udiff, bspl, dense_tmp3, dense_tmp4, dense_tmp5, dense_tmp6, dense_tmp7, kupdate, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + f(k1, uprev, p, t) + a = dt * a0201 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a0301 * k1 + a0302 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a0401 * k1 + a0403 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + + a0706 * k6) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * + (a0801 * k1 + a0804 * k4 + a0805 * k5 + + a0806 * k6 + a0807 * k7) + stage_limiter!(tmp, integrator, p, t + c8 * dt) + f(k8, tmp, p, t + c8 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0901 * k1 + a0904 * k4 + a0905 * k5 + + a0906 * k6 + + a0907 * k7 + a0908 * k8) + stage_limiter!(tmp, integrator, p, t + c9 * dt) + f(k9, tmp, p, t + c9 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + + a1006 * k6 + + a1007 * k7 + a1008 * k8 + a1009 * k9) + stage_limiter!(tmp, integrator, p, t + c10 * dt) + f(k10, tmp, p, t + c10 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + + a1106 * k6 + + a1107 * k7 + a1108 * k8 + a1109 * k9 + + a1110 * k10) + stage_limiter!(tmp, integrator, p, t + c11 * dt) + f(k11, tmp, p, t + c11 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + + a1206 * k6 + + a1207 * k7 + a1208 * k8 + a1209 * k9 + + a1210 * k10 + + a1211 * k11) + stage_limiter!(tmp, integrator, p, t + dt) + f(k12, tmp, p, t + dt) + @.. broadcast=false thread=thread kupdate=b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + + b9 * k9 + + b10 * k10 + b11 * k11 + b12 * k12 + @.. broadcast=false thread=thread u=uprev + dt * kupdate + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + integrator.stats.nf += 12 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * + (k1 * er1 + k6 * er6 + k7 * er7 + + k8 * er8 + k9 * er9 + + k10 * er10 + k11 * er11 + k12 * er12) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + err5 = integrator.opts.internalnorm(atmp, t) # Order 5 + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde6 * k6 + + btilde7 * k7 + + btilde8 * k8 + btilde9 * k9 + + btilde10 * k10 + + btilde11 * k11 + btilde12 * k12) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + err3 = integrator.opts.internalnorm(atmp, t) # Order 3 + err52 = err5 * err5 + if err5 ≈ 0 && err3 ≈ 0 + integrator.EEst = zero(integrator.EEst) + else + integrator.EEst = err52 / sqrt(err52 + 0.01 * err3 * err3) + end + end + f(k13, u, p, t + dt) + integrator.stats.nf += 1 + if integrator.opts.calck + @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache.tab + @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache.tab + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + + a1409 * k9 + + a1410 * k10 + a1411 * k11 + a1412 * k12 + + a1413 * k13) + f(k14, tmp, p, t + c14 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + + a1508 * k8 + + a1511 * k11 + a1512 * k12 + a1513 * k13 + + a1514 * k14) + f(k15, tmp, p, t + c15 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + + a1608 * k8 + + a1609 * k9 + a1613 * k13 + a1614 * k14 + + a1615 * k15) + f(k16, tmp, p, t + c16 * dt) + integrator.stats.nf += 3 + @.. broadcast=false thread=thread udiff=kupdate + @.. broadcast=false thread=thread bspl=k1 - udiff + @.. broadcast=false thread=thread integrator.k[3]=udiff - k13 - bspl + @.. broadcast=false thread=thread integrator.k[4]=d401 * k1 + d406 * k6 + + d407 * k7 + d408 * k8 + + d409 * k9 + d410 * k10 + + d411 * k11 + + d412 * k12 + d413 * k13 + + d414 * k14 + + d415 * k15 + d416 * k16 + @.. broadcast=false thread=thread integrator.k[5]=d501 * k1 + d506 * k6 + + d507 * k7 + d508 * k8 + + d509 * k9 + d510 * k10 + + d511 * k11 + + d512 * k12 + d513 * k13 + + d514 * k14 + + d515 * k15 + d516 * k16 + @.. broadcast=false thread=thread integrator.k[6]=d601 * k1 + d606 * k6 + + d607 * k7 + d608 * k8 + + d609 * k9 + d610 * k10 + + d611 * k11 + + d612 * k12 + d613 * k13 + + d614 * k14 + + d615 * k15 + d616 * k16 + @.. broadcast=false thread=thread integrator.k[7]=d701 * k1 + d706 * k6 + + d707 * k7 + d708 * k8 + + d709 * k9 + d710 * k10 + + d711 * k11 + + d712 * k12 + d713 * k13 + + d714 * k14 + + d715 * k15 + d716 * k16 + end +end + +#= +@muladd function perform_step!(integrator, cache::DP8Cache, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + uidx = eachindex(integrator.uprev) + @unpack c7,c8,c9,c10,c11,c6,c5,c4,c3,c2,b1,b6,b7,b8,b9,b10,b11,b12,btilde1,btilde6,btilde7,btilde8,btilde9,btilde10,btilde11,btilde12,er1,er6,er7,er8,er9,er10,er11,er12,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211 = cache.tab + @unpack k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15,k16,udiff,bspl,dense_tmp3,dense_tmp4,dense_tmp5,dense_tmp6,dense_tmp7,kupdate,utilde,tmp,atmp = cache + f(k1, uprev, p, t) + a = dt*a0201 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2, tmp, p, t + c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0301*k1[i]+a0302*k2[i]) + end + f(k3, tmp, p, t + c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0401*k1[i]+a0403*k3[i]) + end + f(k4, tmp, p, t + c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0501*k1[i]+a0503*k3[i]+a0504*k4[i]) + end + f(k5, tmp, p, t + c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0601*k1[i]+a0604*k4[i]+a0605*k5[i]) + end + f(k6, tmp, p, t + c6*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0701*k1[i]+a0704*k4[i]+a0705*k5[i]+a0706*k6[i]) + end + f(k7, tmp, p, t + c7*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0801*k1[i]+a0804*k4[i]+a0805*k5[i]+a0806*k6[i]+a0807*k7[i]) + end + f(k8, tmp, p, t + c8*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0901*k1[i]+a0904*k4[i]+a0905*k5[i]+a0906*k6[i]+a0907*k7[i]+a0908*k8[i]) + end + f(k9, tmp, p, t + c9*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1001*k1[i]+a1004*k4[i]+a1005*k5[i]+a1006*k6[i]+a1007*k7[i]+a1008*k8[i]+a1009*k9[i]) + end + f(k10, tmp, p, t + c10*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1101*k1[i]+a1104*k4[i]+a1105*k5[i]+a1106*k6[i]+a1107*k7[i]+a1108*k8[i]+a1109*k9[i]+a1110*k10[i]) + end + f(k11, tmp, p, t + c11*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1201*k1[i]+a1204*k4[i]+a1205*k5[i]+a1206*k6[i]+a1207*k7[i]+a1208*k8[i]+a1209*k9[i]+a1210*k10[i]+a1211*k11[i]) + end + f(k12, tmp, p, t+dt) + @tight_loop_macros for i in uidx + @inbounds kupdate[i] = b1*k1[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]+b10*k10[i]+b11*k11[i]+b12*k12[i] + @inbounds u[i] = uprev[i] + dt*kupdate[i] + end + integrator.stats.nf += 12 + if integrator.opts.adaptive + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(k1[i]*er1 + k6[i]*er6 + k7[i]*er7 + k8[i]*er8 + k9[i]*er9 + k10[i]*er10 + k11[i]*er11 + k12[i]*er12) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + err5 = integrator.opts.internalnorm(atmp,t) # Order 5 + @tight_loop_macros for i in uidx + @inbounds utilde[i]= dt*(btilde1*k1[i] + btilde6*k6[i] + btilde7*k7[i] + btilde8*k8[i] + btilde9*k9[i] + btilde10*k10[i] + btilde11*k11[i] + btilde12*k12[i]) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + err3 = integrator.opts.internalnorm(atmp,t) # Order 3 + err52 = err5*err5 + if err5 ≈ 0 && err3 ≈ 0 + integrator.EEst = zero(integrator.EEst) + else + integrator.EEst = err52/sqrt(err52 + 0.01*err3*err3) + end + end + f(k13, u, p, t+dt) + integrator.stats.nf += 1 + if integrator.opts.calck + @unpack c14,c15,c16,a1401,a1407,a1408,a1409,a1410,a1411,a1412,a1413,a1501,a1506,a1507,a1508,a1511,a1512,a1513,a1514,a1601,a1606,a1607,a1608,a1609,a1613,a1614,a1615 = cache.tab + @unpack d401,d406,d407,d408,d409,d410,d411,d412,d413,d414,d415,d416,d501,d506,d507,d508,d509,d510,d511,d512,d513,d514,d515,d516,d601,d606,d607,d608,d609,d610,d611,d612,d613,d614,d615,d616,d701,d706,d707,d708,d709,d710,d711,d712,d713,d714,d715,d716 = cache.tab + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1401*k1[i]+a1407*k7[i]+a1408*k8[i]+a1409*k9[i]+a1410*k10[i]+a1411*k11[i]+a1412*k12[i]+a1413*k13[i]) + end + f(k14, tmp, p, t + c14*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1501*k1[i]+a1506*k6[i]+a1507*k7[i]+a1508*k8[i]+a1511*k11[i]+a1512*k12[i]+a1513*k13[i]+a1514*k14[i]) + end + f(k15, tmp, p, t + c15*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1601*k1[i]+a1606*k6[i]+a1607*k7[i]+a1608*k8[i]+a1609*k9[i]+a1613*k13[i]+a1614*k14[i]+a1615*k15[i]) + end + f(k16, tmp, p, t + c16*dt) + integrator.stats.nf += 3 + @tight_loop_macros for i in uidx + @inbounds udiff[i]= kupdate[i] + @inbounds bspl[i] = k1[i] - udiff[i] + @inbounds integrator.k[3][i] = udiff[i] - k13[i] - bspl[i] + @inbounds integrator.k[4][i] = d401*k1[i]+d406*k6[i]+d407*k7[i]+d408*k8[i]+d409*k9[i]+d410*k10[i]+d411*k11[i]+d412*k12[i]+d413*k13[i]+d414*k14[i]+d415*k15[i]+d416*k16[i] + @inbounds integrator.k[5][i] = d501*k1[i]+d506*k6[i]+d507*k7[i]+d508*k8[i]+d509*k9[i]+d510*k10[i]+d511*k11[i]+d512*k12[i]+d513*k13[i]+d514*k14[i]+d515*k15[i]+d516*k16[i] + @inbounds integrator.k[6][i] = d601*k1[i]+d606*k6[i]+d607*k7[i]+d608*k8[i]+d609*k9[i]+d610*k10[i]+d611*k11[i]+d612*k12[i]+d613*k13[i]+d614*k14[i]+d615*k15[i]+d616*k16[i] + @inbounds integrator.k[7][i] = d701*k1[i]+d706*k6[i]+d707*k7[i]+d708*k8[i]+d709*k9[i]+d710*k10[i]+d711*k11[i]+d712*k12[i]+d713*k13[i]+d714*k14[i]+d715*k15[i]+d716*k16[i] + end + end +end +=# + +function initialize!(integrator, cache::TsitPap8ConstantCache) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +#= +@muladd function perform_step!(integrator, cache::TsitPap8ConstantCache, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + @unpack c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211,a1301,a1304,a1305,a1306,a1307,a1308,a1309,a1310,b1,b6,b7,b8,b9,b10,b11,b12,btilde1,btilde6,btilde7,btilde8,btilde9,btilde10,btilde11,btilde12,btilde13 = cache + k1 = integrator.fsalfirst + a = dt*a0201 + k2 = f(t + c1*dt, @.. broadcast=false uprev+a*k1) + k3 = f(t + c2*dt, @.. broadcast=false uprev+dt*(a0301*k1+a0302*k2)) + k4 = f(t + c3*dt, @.. broadcast=false uprev+dt*(a0401*k1 +a0403*k3)) + k5 = f(t + c4*dt, @.. broadcast=false uprev+dt*(a0501*k1 +a0503*k3+a0504*k4)) + k6 = f(t + c5*dt, @.. broadcast=false uprev+dt*(a0601*k1 +a0604*k4+a0605*k5)) + k7 = f(t + c6*dt, @.. broadcast=false uprev+dt*(a0701*k1 +a0704*k4+a0705*k5+a0706*k6)) + k8 = f(t + c7*dt, @.. broadcast=false uprev+dt*(a0801*k1 +a0804*k4+a0805*k5+a0806*k6+a0807*k7)) + k9 = f(t + c8*dt, @.. broadcast=false uprev+dt*(a0901*k1 +a0904*k4+a0905*k5+a0906*k6+a0907*k7+a0908*k8)) + k10 =f(t + c9*dt, @.. broadcast=false uprev+dt*(a1001*k1 +a1004*k4+a1005*k5+a1006*k6+a1007*k7+a1008*k8+a1009*k9)) + k11= f(t + c10*dt, @.. broadcast=false uprev+dt*(a1101*k1 +a1104*k4+a1105*k5+a1106*k6+a1107*k7+a1108*k8+a1109*k9+a1110*k10)) + k12= f(t+dt, @.. broadcast=false uprev+dt*(a1201*k1 +a1204*k4+a1205*k5+a1206*k6+a1207*k7+a1208*k8+a1209*k9+a1210*k10+a1211*k11)) + k13= f(t+dt, @.. broadcast=false uprev+dt*(a1301*k1 +a1304*k4+a1305*k5+a1306*k6+a1307*k7+a1308*k8+a1309*k9+a1310*k10)) + u = @.. broadcast=false uprev + dt*(b1*k1+b6*k6+b7*k7+b8*k8+b9*k9+b10*k10+b11*k11+b12*k12) + if integrator.opts.adaptive + utilde = @.. broadcast=false dt*(btilde1*k1 + btilde6*k6 + btilde7*k7 + btilde8*k8 + btilde9*k9 + btilde10*k10 + btilde11*k11 + btilde12*k12 + btilde13*k13) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + integrator.EEst = integrator.opts.internalnorm(atmp,t) + end + integrator.fsallast = f(u, p, t+dt) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end +=# + +@muladd function perform_step!(integrator, cache::TsitPap8ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13 = cache + k1 = integrator.fsalfirst + a = dt * a0201 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a0301 * k1 + a0302 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a0401 * k1 + a0403 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4), p, t + c4 * dt) + k6 = f(uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5), p, t + c5 * dt) + k7 = f(uprev + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6), p, t + c6 * dt) + k8 = f( + uprev + dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + a0807 * k7), p, + t + c7 * dt) + k9 = f( + uprev + + dt * + (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + a0907 * k7 + a0908 * k8), + p, + t + c8 * dt) + k10 = f( + uprev + + dt * + (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + a1007 * k7 + a1008 * k8 + + a1009 * k9), + p, + t + c9 * dt) + k11 = f( + uprev + + dt * + (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + a1107 * k7 + a1108 * k8 + + a1109 * k9 + a1110 * k10), + p, + t + c10 * dt) + k12 = f( + uprev + + dt * + (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + a1207 * k7 + a1208 * k8 + + a1209 * k9 + a1210 * k10 + a1211 * k11), + p, + t + dt) + k13 = f( + uprev + + dt * + (a1301 * k1 + a1304 * k4 + a1305 * k5 + a1306 * k6 + a1307 * k7 + a1308 * k8 + + a1309 * k9 + a1310 * k10), + p, + t + dt) + integrator.stats.nf += 12 + u = uprev + + dt * (b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + b10 * k10 + b11 * k11 + + b12 * k12) + if integrator.opts.adaptive + utilde = dt * + (btilde1 * k1 + btilde6 * k6 + btilde7 * k7 + btilde8 * k8 + btilde9 * k9 + + btilde10 * k10 + btilde11 * k11 + btilde12 * k12 + btilde13 * k13) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::TsitPap8Cache) + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = cache.k + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::TsitPap8Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13 = cache.tab + @unpack k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, tmp, atmp, k, stage_limiter!, step_limiter!, thread = cache + k1 = cache.fsalfirst + f(k1, uprev, p, t) + a = dt * a0201 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a0301 * k1 + a0302 * k2) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a0401 * k1 + a0403 * k3) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k6, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + + a0706 * k6) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k7, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * + (a0801 * k1 + a0804 * k4 + a0805 * k5 + + a0806 * k6 + a0807 * k7) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k8, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a0901 * k1 + a0904 * k4 + a0905 * k5 + + a0906 * k6 + + a0907 * k7 + a0908 * k8) + stage_limiter!(tmp, integrator, p, t + c8 * dt) + f(k9, tmp, p, t + c8 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + + a1006 * k6 + + a1007 * k7 + a1008 * k8 + a1009 * k9) + stage_limiter!(tmp, integrator, p, t + c9 * dt) + f(k10, tmp, p, t + c9 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + + a1106 * k6 + + a1107 * k7 + a1108 * k8 + a1109 * k9 + + a1110 * k10) + stage_limiter!(tmp, integrator, p, t + c10 * dt) + f(k11, tmp, p, t + c10 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + + a1206 * k6 + + a1207 * k7 + a1208 * k8 + a1209 * k9 + + a1210 * k10 + + a1211 * k11) + stage_limiter!(tmp, integrator, p, t + dt) + f(k12, tmp, p, t + dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a1301 * k1 + a1304 * k4 + a1305 * k5 + + a1306 * k6 + + a1307 * k7 + a1308 * k8 + a1309 * k9 + + a1310 * k10) + stage_limiter!(tmp, integrator, p, t + dt) + f(k13, tmp, p, t + dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + + b10 * k10 + + b11 * k11 + b12 * k12) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + integrator.stats.nf += 13 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde6 * k6 + + btilde7 * k7 + + btilde8 * k8 + btilde9 * k9 + + btilde10 * k10 + + btilde11 * k11 + btilde12 * k12 + + btilde13 * k13) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + f(k, u, p, t + dt) + integrator.stats.nf += 1 + return nothing +end + +#= +@muladd function perform_step!(integrator, cache::TsitPap8Cache, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + uidx = eachindex(integrator.uprev) + @unpack c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211,a1301,a1304,a1305,a1306,a1307,a1308,a1309,a1310,b1,b6,b7,b8,b9,b10,b11,b12,btilde1,btilde6,btilde7,btilde8,btilde9,btilde10,btilde11,btilde12,btilde13 = cache.tab + @unpack k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,utilde,tmp,atmp,k = cache + k1 = cache.fsalfirst + f(k1, uprev, p, t) + a = dt*a0201 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2, tmp, p, t + c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0301*k1[i]+a0302*k2[i]) + end + f(k3, tmp, p, t + c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0401*k1[i]+a0403*k3[i]) + end + f(k4, tmp, p, t + c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0501*k1[i]+a0503*k3[i]+a0504*k4[i]) + end + f(k5, tmp, p, t + c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0601*k1[i]+a0604*k4[i]+a0605*k5[i]) + end + f(k6, tmp, p, t + c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0701*k1[i]+a0704*k4[i]+a0705*k5[i]+a0706*k6[i]) + end + f(k7, tmp, p, t + c6*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0801*k1[i]+a0804*k4[i]+a0805*k5[i]+a0806*k6[i]+a0807*k7[i]) + end + f(k8, tmp, p, t + c7*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a0901*k1[i]+a0904*k4[i]+a0905*k5[i]+a0906*k6[i]+a0907*k7[i]+a0908*k8[i]) + end + f(k9, tmp, p, t + c8*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1001*k1[i]+a1004*k4[i]+a1005*k5[i]+a1006*k6[i]+a1007*k7[i]+a1008*k8[i]+a1009*k9[i]) + end + f(k10, tmp, p, t + c9*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1101*k1[i]+a1104*k4[i]+a1105*k5[i]+a1106*k6[i]+a1107*k7[i]+a1108*k8[i]+a1109*k9[i]+a1110*k10[i]) + end + f(k11, tmp, p, t + c10*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1201*k1[i]+a1204*k4[i]+a1205*k5[i]+a1206*k6[i]+a1207*k7[i]+a1208*k8[i]+a1209*k9[i]+a1210*k10[i]+a1211*k11[i]) + end + f(k12, tmp, p, t+dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a1301*k1[i]+a1304*k4[i]+a1305*k5[i]+a1306*k6[i]+a1307*k7[i]+a1308*k8[i]+a1309*k9[i]+a1310*k10[i]) + end + f(k13, tmp, p, t+dt) + @tight_loop_macros for i in uidx + @inbounds u[i] = uprev[i] + dt*(b1*k1[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]+b10*k10[i]+b11*k11[i]+b12*k12[i]) + end + integrator.stats.nf += 13 + if integrator.opts.adaptive + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde6*k6[i] + btilde7*k7[i] + btilde8*k8[i] + btilde9*k9[i] + btilde10*k10[i] + btilde11*k11[i] + btilde12*k12[i] + btilde13*k13[i]) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + integrator.EEst = integrator.opts.internalnorm(atmp,t) + end + f(k, u, p, t+dt) + integrator.stats.nf += 1 +end +=# + +function initialize!(integrator, cache::PFRK87ConstantCache) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::PFRK87ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack α0201, α0301, α0401, α0501, α0601, α0701, α0302, α0403, α0503, α0504, α0604, α0704, α0605, α0705, α0706, α0908, α1008, α1108, α1208, α1308, α1009, α1109, α1209, α1309, α1110, α1210, α1310, α1211, α1311, β1, β6, β7, β8, β9, β10, β11, β12, β13, β1tilde, β6tilde, β7tilde, β8tilde, β9tilde, β10tilde, β11tilde, β12tilde, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 = cache + alg = unwrap_alg(integrator, false) + ν = alg.omega * dt + νsq = ν^2 + + c_ν = -0.19781108078634084 - (0.164050909125528499 * νsq) + + (0.042578310088756321 * (νsq^2)) - (0.002300513610963998 * (νsq^3)) + + (0.000033467244551879287 * (νsq^4)) - + (7.8661142036921924 * (1 / 100000000) * (νsq^5)) + d_ν = 1 - (0.296457092123567400 * νsq) + (0.0015793885907465726 * (νsq^2)) - + (0.00018913011771688527 * (νsq^3)) + (0.000017089234650765179 * (νsq^4)) - + (1.2705211682518626 * (1 / 10000000) * (νsq^5)) + + α0807 = c_ν / d_ν + α0801 = 0.026876256 + 0.0576576 * α0807 + α0804 = 0.22464336 - 0.944944 * α0807 + α0805 = 0.000369024 - 0.2061696 * α0807 + α0806 = 0.21311136 + 0.093456 * α0807 + α0901 = 0.07239997637512857 + 0.01913119863380767 * α0807 + α0904 = -0.688400520601143 - 0.3135390887207368 * α0807 + α0905 = -0.17301267570583073 - 0.06840852844816077 * α0807 + α0906 = 0.1440060555560846 + 0.031009360422930017 * α0807 + α0907 = 0.9982362892760762 + 0.33180705811215994 * α0807 + α1001 = 0.16261514523236525 - 0.12125171966747463 * α0807 + α1004 = -2.1255544052061124 + 1.9871809612169453 * α0807 + α1005 = -0.216403903283323 + 0.43356675517460624 * α0807 + α1006 = -0.060417230254934076 - 0.1965343807796979 * α0807 + α1007 = 2.4846281621788395 - 2.102961615944379 * α0807 + α1101 = -1.0320124180911034 + 1.061943768952537 * α0807 + α1104 = 13.666683232895137 - 17.40407843561103 * α0807 + α1105 = 0.25990355211486116 - 3.797253476860588 * α0807 + α1106 = -5.759316475814002 + 1.7212824826428488 * α0807 + α1107 = -12.822511612651839 + 18.41810566087623 * α0807 + α1201 = 0.2478349764611783 - 0.06383934946543009 * α0807 + α1204 = -4.593782880309185 + 1.046256005127882 * α0807 + α1205 = -0.39566692537411896 + 0.22827403748244698 * α0807 + α1206 = -3.0673550479691665 - 0.10347586863902129 * α0807 + α1207 = 5.386688702227177 - 1.1072148245058775 * α0807 + α1301 = 0.7332242174431163 - 0.5164807626867616 * α0807 + α1304 = -10.196728938160977 + 8.464545832921925 * α0807 + α1305 = -0.43865244706547707 + 1.846809999910238 * α0807 + α1306 = 0.5693856884667226 - 0.8371528845746959 * α0807 + α1307 = 10.52865228002416 - 8.957722185570706 * α0807 + + k1 = integrator.fsalfirst + k2 = f(uprev + dt * α0201 * k1, p, t + c2 * dt) + k3 = f(uprev + dt * (α0301 * k1 + α0302 * k2), p, t + c3 * dt) + k4 = f(uprev + dt * (α0401 * k1 + α0403 * k3), p, t + c4 * dt) + k5 = f(uprev + dt * (α0501 * k1 + α0503 * k3 + α0504 * k4), p, t + c5 * dt) + k6 = f(uprev + dt * (α0601 * k1 + α0604 * k4 + α0605 * k5), p, t + c6 * dt) + k7 = f(uprev + dt * (α0701 * k1 + α0704 * k4 + α0705 * k5 + α0706 * k6), p, t + c7 * dt) + k8 = f( + uprev + dt * (α0801 * k1 + α0804 * k4 + α0805 * k5 + α0806 * k6 + α0807 * k7), p, + t + c8 * dt) + k9 = f( + uprev + + dt * + (α0901 * k1 + α0904 * k4 + α0905 * k5 + α0906 * k6 + α0907 * k7 + α0908 * k8), + p, + t + c9 * dt) + k10 = f( + uprev + + dt * + (α1001 * k1 + α1004 * k4 + α1005 * k5 + α1006 * k6 + α1007 * k7 + α1008 * k8 + + α1009 * k9), + p, + t + c10 * dt) + k11 = f( + uprev + + dt * + (α1101 * k1 + α1104 * k4 + α1105 * k5 + α1106 * k6 + α1107 * k7 + α1108 * k8 + + α1109 * k9 + α1110 * k10), + p, + t + c11 * dt) + k12 = f( + uprev + + dt * + (α1201 * k1 + α1204 * k4 + α1205 * k5 + α1206 * k6 + α1207 * k7 + α1208 * k8 + + α1209 * k9 + α1210 * k10 + α1211 * k11), + p, + t + c12 * dt) + k13 = f( + uprev + + dt * + (α1301 * k1 + α1304 * k4 + α1305 * k5 + α1306 * k6 + α1307 * k7 + α1308 * k8 + + α1309 * k9 + α1310 * k10 + α1311 * k11), + p, + t + c13 * dt) + integrator.stats.nf += 12 + u = uprev + + dt * (β1 * k1 + β6 * k6 + β7 * k7 + β8 * k8 + β9 * k9 + β10 * k10 + β11 * k11 + + β12 * k12 + β13 * k13) + if integrator.opts.adaptive + utilde = dt * + (β1tilde * k1 + β6tilde * k6 + β7tilde * k7 + β8tilde * k8 + β9tilde * k9 + + β10tilde * k10 + β11tilde * k11 + β12tilde * k12) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::PFRK87Cache) + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = cache.k + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::PFRK87Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack α0201, α0301, α0401, α0501, α0601, α0701, α0302, α0403, α0503, α0504, α0604, α0704, α0605, α0705, α0706, α0908, α1008, α1108, α1208, α1308, α1009, α1109, α1209, α1309, α1110, α1210, α1310, α1211, α1311, β1, β6, β7, β8, β9, β10, β11, β12, β13, β1tilde, β6tilde, β7tilde, β8tilde, β9tilde, β10tilde, β11tilde, β12tilde, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 = cache.tab + @unpack k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, tmp, atmp, k, stage_limiter!, step_limiter!, thread = cache + + alg = unwrap_alg(integrator, false) + ν = alg.omega * dt + νsq = ν^2 + + c_ν = -0.19781108078634084 - (0.164050909125528499 * νsq) + + (0.042578310088756321 * (νsq^2)) - (0.002300513610963998 * (νsq^3)) + + (0.000033467244551879287 * (νsq^4)) - (7.8661142036921924 * (10^(-8)) * (νsq^5)) + d_ν = 1 - (0.296457092123567400 * νsq) + (0.0015793885907465726 * (νsq^2)) - + (0.00018913011771688527 * (νsq^3)) + (0.000017089234650765179 * (νsq^4)) - + (1.2705211682518626 * (10^(-7)) * (νsq^5)) + + α0807 = c_ν / d_ν + α0801 = 0.026876256 + 0.0576576 * α0807 + α0804 = 0.22464336 - 0.944944 * α0807 + α0805 = 0.000369024 - 0.2061696 * α0807 + α0806 = 0.21311136 + 0.093456 * α0807 + α0901 = 0.07239997637512857 + 0.01913119863380767 * α0807 + α0904 = -0.688400520601143 - 0.3135390887207368 * α0807 + α0905 = -0.17301267570583073 - 0.06840852844816077 * α0807 + α0906 = 0.1440060555560846 + 0.031009360422930017 * α0807 + α0907 = 0.9982362892760762 + 0.33180705811215994 * α0807 + α1001 = 0.16261514523236525 - 0.12125171966747463 * α0807 + α1004 = -2.1255544052061124 + 1.9871809612169453 * α0807 + α1005 = -0.216403903283323 + 0.43356675517460624 * α0807 + α1006 = -0.060417230254934076 - 0.1965343807796979 * α0807 + α1007 = 2.4846281621788395 - 2.102961615944379 * α0807 + α1101 = -1.0320124180911034 + 1.061943768952537 * α0807 + α1104 = 13.666683232895137 - 17.40407843561103 * α0807 + α1105 = 0.25990355211486116 - 3.797253476860588 * α0807 + α1106 = -5.759316475814002 + 1.7212824826428488 * α0807 + α1107 = -12.822511612651839 + 18.41810566087623 * α0807 + α1201 = 0.2478349764611783 - 0.06383934946543009 * α0807 + α1204 = -4.593782880309185 + 1.046256005127882 * α0807 + α1205 = -0.39566692537411896 + 0.22827403748244698 * α0807 + α1206 = -3.0673550479691665 - 0.10347586863902129 * α0807 + α1207 = 5.386688702227177 - 1.1072148245058775 * α0807 + α1301 = 0.7332242174431163 - 0.5164807626867616 * α0807 + α1304 = -10.196728938160977 + 8.464545832921925 * α0807 + α1305 = -0.43865244706547707 + 1.846809999910238 * α0807 + α1306 = 0.5693856884667226 - 0.8371528845746959 * α0807 + α1307 = 10.52865228002416 - 8.957722185570706 * α0807 + + k1 = cache.fsalfirst + f(k1, uprev, p, t) + @.. broadcast=false thread=thread tmp=uprev + dt * α0201 * k1 + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (α0301 * k1 + α0302 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (α0401 * k1 + α0403 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α0501 * k1 + α0503 * k3 + α0504 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α0601 * k1 + α0604 * k4 + α0605 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α0701 * k1 + α0704 * k4 + α0705 * k5 + + α0706 * k6) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * + (α0801 * k1 + α0804 * k4 + α0805 * k5 + + α0806 * k6 + α0807 * k7) + stage_limiter!(tmp, integrator, p, t + c8 * dt) + f(k8, tmp, p, t + c8 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α0901 * k1 + α0904 * k4 + α0905 * k5 + + α0906 * k6 + + α0907 * k7 + α0908 * k8) + stage_limiter!(tmp, integrator, p, t + c9 * dt) + f(k9, tmp, p, t + c9 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α1001 * k1 + α1004 * k4 + α1005 * k5 + + α1006 * k6 + + α1007 * k7 + α1008 * k8 + α1009 * k9) + stage_limiter!(tmp, integrator, p, t + c10 * dt) + f(k10, tmp, p, t + c10 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α1101 * k1 + α1104 * k4 + α1105 * k5 + + α1106 * k6 + + α1107 * k7 + α1108 * k8 + α1109 * k9 + + α1110 * k10) + stage_limiter!(tmp, integrator, p, t + c11 * dt) + f(k11, tmp, p, t + c11 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α1201 * k1 + α1204 * k4 + α1205 * k5 + + α1206 * k6 + + α1207 * k7 + α1208 * k8 + α1209 * k9 + + α1210 * k10 + + α1211 * k11) + stage_limiter!(tmp, integrator, p, t + c12 * dt) + f(k12, tmp, p, t + c12 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (α1301 * k1 + α1304 * k4 + α1305 * k5 + + α1306 * k6 + + α1307 * k7 + α1308 * k8 + α1309 * k9 + + α1310 * k10 + + α1311 * k11) + stage_limiter!(tmp, integrator, p, t + c13 * dt) + f(k13, tmp, p, t + c13 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (β1 * k1 + β6 * k6 + β7 * k7 + β8 * k8 + β9 * k9 + + β10 * k10 + + β11 * k11 + β12 * k12 + β13 * k13) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + integrator.stats.nf += 13 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (β1tilde * k1 + β6tilde * k6 + + β7tilde * k7 + + β8tilde * k8 + β9tilde * k9 + + β10tilde * k10 + + β11tilde * k11 + β12tilde * k12) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + f(k, u, p, t + dt) + integrator.stats.nf += 1 + return nothing +end diff --git a/src/perform_step/kencarp_kvaerno_perform_step.jl b/src/perform_step/kencarp_kvaerno_perform_step.jl new file mode 100644 index 0000000000..1b3d6f1a7b --- /dev/null +++ b/src/perform_step/kencarp_kvaerno_perform_step.jl @@ -0,0 +1,2665 @@ +function initialize!(integrator, + cache::Union{Kvaerno3ConstantCache, + KenCarp3ConstantCache, + Kvaerno4ConstantCache, + KenCarp4ConstantCache, + KenCarp47ConstantCache, + Kvaerno5ConstantCache, + KenCarp5ConstantCache, + KenCarp58ConstantCache, + CFNLIRK3ConstantCache + }) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function initialize!(integrator, + cache::Union{Kvaerno3Cache, + KenCarp3Cache, + Kvaerno4Cache, + KenCarp4Cache, + Kvaerno5Cache, + KenCarp5Cache, + CFNLIRK3Cache, + KenCarp47Cache, + KenCarp58Cache + }) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::Kvaerno3ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32 = cache.tab + alg = unwrap_alg(integrator, true) + + # calculate W + markfirststage!(nlsolver) + + # FSAL Step 1 + nlsolver.z = z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation for guess + nlsolver.z = z₂ = z₁ + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess is from Hermite derivative on z₁ and z₂ + nlsolver.z = z₃ = α31 * z₁ + α32 * z₂ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = a31 * z₁ + a32 * z₂ + γ * z₃ # use yhat as prediction + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = 1 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₄ + + ################################### Finalize + + if integrator.opts.adaptive + tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₄ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::Kvaerno3Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, atmp, nlsolver, step_limiter! = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + # FSAL Step 1 + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation for guess + copyto!(z₂, z₁) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + # Guess is from Hermite derivative on z₁ and z₂ + @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ + nlsolver.z = z₃ + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if cache isa Kvaerno3Cache + @.. broadcast=false z₄=a31 * z₁ + a32 * z₂ + γ * z₃ # use yhat as prediction + elseif cache isa KenCarp3Cache + @unpack α41, α42 = cache.tab + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + end + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = 1 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₄ + + step_limiter!(u, integrator, p, t + dt) + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₄ / dt +end + +@muladd function perform_step!(integrator, cache::KenCarp3ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4, ebtilde1, ebtilde2, ebtilde3, ebtilde4 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + if integrator.f isa SplitFunction + # Explicit tableau is not FSAL + # Make this not compute on repeat + z₁ = dt * f(uprev, p, t) + else + # FSAL Step 1 + z₁ = dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation for guess + nlsolver.z = z₂ = z₁ + + nlsolver.tmp = uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + k1 = dt * integrator.fsalfirst - z₁ + nlsolver.tmp += ea21 * k1 + end + + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ = z₂ + u = nlsolver.tmp + γ * z₂ + k2 = dt * f2(u, p, t + 2γdt) + integrator.stats.nf2 += 1 + tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + z₃ = α31 * z₁ + α32 * z₂ + tmp = uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + nlsolver.tmp = tmp + nlsolver.c = c3 + + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ = z₂ + u = nlsolver.tmp + γ * z₃ + k3 = dt * f2(u, p, t + c3 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 + else + @unpack α41, α42 = cache.tab + z₄ = α41 * z₁ + α42 * z₂ + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + nlsolver.c = 1 + nlsolver.tmp = tmp + + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₄ + if integrator.f isa SplitFunction + k4 = dt * f2(u, p, t + dt) + integrator.stats.nf2 += 1 + u = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + eb2 * k2 + + eb3 * k3 + eb4 * k4 + end + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + ebtilde1 * k1 + ebtilde2 * k2 + ebtilde3 * k3 + ebtilde4 * k4 + else + tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + end + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.k[1] = integrator.fsalfirst + integrator.fsallast = integrator.f(u, p, t + dt) + integrator.k[2] = integrator.fsallast + else + integrator.fsallast = z₄ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + end + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::KenCarp3Cache, repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + @unpack z₁, z₂, z₃, z₄, k1, k2, k3, k4, atmp, nlsolver, step_limiter! = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4 = cache.tab + @unpack ebtilde1, ebtilde2, ebtilde3, ebtilde4 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail + # Explicit tableau is not FSAL + # Make this not compute on repeat + f(z₁, integrator.uprev, p, integrator.t) + z₁ .*= dt + else + # FSAL Step 1 + @.. broadcast=false z₁=dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation for guess + copyto!(z₂, z₁) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ + @.. broadcast=false tmp+=ea21 * k1 + end + + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ .= z₂ + @.. broadcast=false u=tmp + γ * z₂ + f2(k2, u, p, t + 2γdt) + k2 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ .= z₂ + @.. broadcast=false u=tmp + γ * z₃ + f2(k3, u, p, t + c3 * dt) + k3 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + + ea42 * k2 + ea43 * k3 + else + @unpack α41, α42 = cache.tab + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + + nlsolver.c = 1 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₄ + if integrator.f isa SplitFunction + f2(k4, u, p, t + dt) + k4 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false u=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + + eb2 * k2 + eb3 * k3 + eb4 * k4 + end + + step_limiter!(u, integrator, p, t + dt) + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + + btilde4 * z₄ + ebtilde1 * k1 + ebtilde2 * k2 + + ebtilde3 * k3 + ebtilde4 * k4 + else + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + + btilde4 * z₄ + end + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.f(integrator.fsallast, u, p, t + dt) + else + @.. broadcast=false integrator.fsallast=z₄ / dt + end +end + +@muladd function perform_step!(integrator, cache::CFNLIRK3ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, c2, c3, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + if integrator.f isa SplitFunction + # Explicit tableau is not FSAL + # Make this not compute on repeat + z₁ = dt .* f(uprev, p, t) + else + # FSAL Step 1 + z₁ = dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation for guess + nlsolver.z = z₂ = z₁ + + nlsolver.tmp = uprev + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + k1 = dt .* f2(uprev, p, t) + nlsolver.tmp += ea21 * k1 + end + + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ = z₂ + u = nlsolver.tmp + γ * z₂ + k2 = dt * f2(u, p, t + c2 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + z₃ = z₂ + tmp = uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + nlsolver.tmp = tmp + nlsolver.c = c3 + + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ = z₃ + u = nlsolver.tmp + γ * z₃ + k3 = dt * f2(u, p, t + c3 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 + else + z₄ = z₃ + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + nlsolver.c = 1 + nlsolver.tmp = tmp + + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₄ + if integrator.f isa SplitFunction + k4 = dt * f2(u, p, t + dt) + integrator.stats.nf2 += 1 + u = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + eb2 * k2 + + eb3 * k3 + eb4 * k4 + end + + ################################### Finalize + + if integrator.f isa SplitFunction + integrator.k[1] = integrator.fsalfirst + integrator.fsallast = integrator.f(u, p, t + dt) + integrator.k[2] = integrator.fsallast + else + integrator.fsallast = z₄ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + end + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::CFNLIRK3Cache, repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + @unpack z₁, z₂, z₃, z₄, k1, k2, k3, k4, atmp, nlsolver = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a42, a43, c2, c3 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4 = cache.tab + + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail + f(z₁, integrator.uprev, p, integrator.t) + z₁ .*= dt + else + # FSAL Step 1 + @.. broadcast=false z₁=dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation for guess + copyto!(z₂, z₁) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ + @.. broadcast=false tmp+=ea21 * k1 + end + + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ .= z₂ + @.. broadcast=false u=tmp + γ * z₂ + f2(k2, u, p, t + c2 * dt) + k2 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + @.. broadcast=false z₃=z₂ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ .= z₂ + @.. broadcast=false u=tmp + γ * z₃ + f2(k3, u, p, t + c3 * dt) + k3 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + + ea42 * k2 + ea43 * k3 + else + @.. broadcast=false z₄=z₂ + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + + nlsolver.c = 1 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₄ + if integrator.f isa SplitFunction + f2(k4, u, p, t + dt) + k4 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false u=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + + eb2 * k2 + eb3 * k3 + eb4 * k4 + end + + if integrator.f isa SplitFunction + integrator.f(integrator.fsallast, u, p, t + dt) + else + @.. broadcast=false integrator.fsallast=z₄ / dt + end +end + +@muladd function perform_step!(integrator, cache::Kvaerno4ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, c3, c4 = cache.tab + @unpack α21, α31, α32, α41, α42 = cache.tab + @unpack btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + ##### Step 1 + + z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = zero(u) + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + nlsolver.z = z₃ = α31 * z₁ + α32 * z₂ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = α41 * z₁ + α42 * z₂ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use yhat2 for prediction + nlsolver.z = z₅ = a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = 1 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₄ + + ################################### Finalize + + if integrator.opts.adaptive + tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₅ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::Kvaerno4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, step_limiter! = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, c3, c4 = cache.tab + @unpack α21, α31, α32, α41, α42 = cache.tab + @unpack btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + ##### Step 1 + + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Allow other choices here + z₂ .= zero(eltype(u)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ + nlsolver.z = z₃ + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use yhat prediction + @.. broadcast=false z₅=a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + nlsolver.z = z₅ + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = 1 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₅ + + step_limiter!(u, integrator, p, t + dt) + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₅ / dt +end + +@muladd function perform_step!(integrator, cache::KenCarp4ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c3, c4, c5 = cache.tab + @unpack α31, α32, α41, α42, α51, α52, α53, α54, α61, α62, α63, α64, α65 = cache.tab + @unpack btilde1, btilde3, btilde4, btilde5, btilde6 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab + @unpack eb1, eb3, eb4, eb5, eb6 = cache.tab + @unpack ebtilde1, ebtilde3, ebtilde4, ebtilde5, ebtilde6 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + if integrator.f isa SplitFunction + # Explicit tableau is not FSAL + # Make this not compute on repeat + z₁ = dt .* f(uprev, p, t) + else + # FSAL Step 1 + z₁ = dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = z₁ + + tmp = uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + k1 = dt * integrator.fsalfirst - z₁ + tmp += ea21 * k1 + end + nlsolver.tmp = tmp + nlsolver.c = 2γ + + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ = z₂ + u = nlsolver.tmp + γ * z₂ + k2 = dt * f2(u, p, t + 2γdt) + integrator.stats.nf2 += 1 + tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + z₃ = α31 * z₁ + α32 * z₂ + tmp = uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + nlsolver.tmp = tmp + nlsolver.c = c3 + + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ = z₂ + u = nlsolver.tmp + γ * z₃ + k3 = dt * f2(u, p, t + c3 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 + else + z₄ = α41 * z₁ + α42 * z₂ + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + nlsolver.tmp = tmp + nlsolver.c = c4 + + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ = z₄ + u = nlsolver.tmp + γ * z₄ + k4 = dt * f2(u, p, t + c4 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea52 * k2 + + ea53 * k3 + ea54 * k4 + else + z₅ = α51 * z₁ + α52 * z₂ + α53 * z₃ + α54 * z₄ + tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + nlsolver.tmp = tmp + nlsolver.c = c5 + + u = nlsolver.tmp + γ * z₅ + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ = z₅ + u = nlsolver.tmp + γ * z₅ + k5 = dt * f2(u, p, t + c5 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + ea62 * k2 + + ea63 * k3 + ea64 * k4 + ea65 * k5 + else + z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ + α64 * z₄ + α65 * z₅ + tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + nlsolver.tmp = tmp + nlsolver.c = 1 + + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₆ + if integrator.f isa SplitFunction + k6 = dt * f2(u, p, t + dt) + integrator.stats.nf2 += 1 + u = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ + eb1 * k1 + + eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + end + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + tmp = btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + + ebtilde1 * k1 + ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + + ebtilde6 * k6 + else + tmp = btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + end + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.k[1] = integrator.fsalfirst + integrator.fsallast = integrator.f(u, p, t + dt) + integrator.k[2] = integrator.fsallast + else + integrator.fsallast = z₆ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + end + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::KenCarp4Cache, repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, step_limiter! = cache + @unpack tmp = nlsolver + @unpack k1, k2, k3, k4, k5, k6 = cache + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c3, c4, c5 = cache.tab + @unpack α31, α32, α41, α42, α51, α52, α53, α54, α61, α62, α63, α64, α65 = cache.tab + @unpack btilde1, btilde3, btilde4, btilde5, btilde6 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab + @unpack eb1, eb3, eb4, eb5, eb6 = cache.tab + @unpack ebtilde1, ebtilde3, ebtilde4, ebtilde5, ebtilde6 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + ##### Step 1 + + if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail + # Explicit tableau is not FSAL + # Make this not compute on repeat + f(z₁, integrator.uprev, p, integrator.t) + z₁ .*= dt + else + # FSAL Step 1 + @.. broadcast=false z₁=dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Allow other choices here + copyto!(z₂, z₁) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ + @.. broadcast=false tmp+=ea21 * k1 + end + + nlsolver.c = 2γ + markfirststage!(nlsolver) + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ .= z₂ + @.. broadcast=false u=tmp + γ * z₂ + f2(k2, u, p, t + 2γdt) + k2 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ .= z₂ + @.. broadcast=false u=tmp + γ * z₃ + f2(k3, u, p, t + c3 * dt) + k3 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + + ea42 * k2 + ea43 * k3 + else + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ .= z₄ + @.. broadcast=false u=tmp + γ * z₄ + f2(k4, u, p, t + c4 * dt) + k4 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + + ea51 * k1 + ea52 * k2 + ea53 * k3 + ea54 * k4 + else + @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ + α53 * z₃ + α54 * z₄ + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ .= z₅ + @.. broadcast=false u=tmp + γ * z₅ + f2(k5, u, p, t + c5 * dt) + k5 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + + ea61 * k1 + ea62 * k2 + ea63 * k3 + ea64 * k4 + ea65 * k5 + else + @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ + α64 * z₄ + α65 * z₅ + @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + + nlsolver.c = 1 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₆ + if integrator.f isa SplitFunction + f2(k6, u, p, t + dt) + k6 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false u=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ + + eb1 * k1 + eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + end + + step_limiter!(u, integrator, p, t + dt) + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + @.. broadcast=false tmp=btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + btilde6 * z₆ + ebtilde1 * k1 + + ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + + ebtilde6 * k6 + else + @.. broadcast=false tmp=btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + btilde6 * z₆ + end + + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.f(integrator.fsallast, u, p, t + dt) + else + @.. broadcast=false integrator.fsallast=z₆ / dt + end +end + +@muladd function perform_step!(integrator, cache::Kvaerno5ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab + @unpack btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + @unpack α31, α32, α41, α42, α43, α51, α52, α53, α61, α62, α63 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + ##### Step 1 + + z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = z₁ + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + nlsolver.z = z₃ = α31 * z₁ + α32 * z₂ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = α41 * z₁ + α42 * z₂ + α43 * z₃ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = z₅ = α51 * z₁ + α52 * z₂ + α53 * z₃ + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ + + nlsolver.tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + # Prediction from embedding + nlsolver.z = z₇ = a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ + + nlsolver.tmp = uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = 1 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₇ + + ################################### Finalize + + if integrator.opts.adaptive + tmp = btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + + btilde7 * z₇ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₇ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::Kvaerno5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, step_limiter! = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab + @unpack btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + @unpack α31, α32, α41, α42, α43, α51, α52, α53, α61, α62, α63 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + ##### Step 1 + + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Allow other choices here + copyto!(z₂, z₁) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ + nlsolver.z = z₃ + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + α43 * z₃ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ + α53 * z₃ + nlsolver.z = z₅ + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ + nlsolver.z = z₆ + + @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + # Prediction is embedded method + @.. broadcast=false z₇=a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ + nlsolver.z = z₇ + + @.. broadcast=false tmp=uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = 1 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₇ + + step_limiter!(u, integrator, p, t + dt) + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₇ / dt +end + +@muladd function perform_step!(integrator, cache::KenCarp5ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab + @unpack α31, α32, α41, α42, α51, α52, α61, α62, α71, α72, α73, α74, α75, α81, α82, α83, α84, α85 = cache.tab + @unpack btilde1, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea43, ea51, ea53, ea54, ea61, ea63, ea64, ea65 = cache.tab + @unpack ea71, ea73, ea74, ea75, ea76, ea81, ea83, ea84, ea85, ea86, ea87 = cache.tab + @unpack eb1, eb4, eb5, eb6, eb7, eb8 = cache.tab + @unpack ebtilde1, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + ##### Step 1 + + if integrator.f isa SplitFunction + # Explicit tableau is not FSAL + # Make this not compute on repeat + z₁ = dt .* f(uprev, p, t) + else + # FSAL Step 1 + z₁ = dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = z₁ + + tmp = uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + k1 = dt * integrator.fsalfirst - z₁ + tmp += ea21 * k1 + end + nlsolver.tmp = tmp + nlsolver.c = 2γ + + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ = z₂ + u = nlsolver.tmp + γ * z₂ + k2 = dt * f2(u, p, t + 2γdt) + integrator.stats.nf2 += 1 + tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + z₃ = α31 * z₁ + α32 * z₂ + tmp = uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + nlsolver.c = c3 + nlsolver.tmp = tmp + + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ = z₂ + u = nlsolver.tmp + γ * z₃ + k3 = dt * f2(u, p, t + c3 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a41 * z₁ + a43 * z₃ + ea41 * k1 + ea43 * k3 + else + z₄ = α41 * z₁ + α42 * z₂ + tmp = uprev + a41 * z₁ + a43 * z₃ + end + nlsolver.z = z₄ + nlsolver.c = c4 + nlsolver.tmp = tmp + + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ = z₂ + u = nlsolver.tmp + γ * z₄ + k4 = dt * f2(u, p, t + c4 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea53 * k3 + ea54 * k4 + else + z₅ = α51 * z₁ + α52 * z₂ + tmp = uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + nlsolver.c = c5 + nlsolver.tmp = tmp + + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ = z₃ + u = nlsolver.tmp + γ * z₅ + k5 = dt * f2(u, p, t + c5 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + ea63 * k3 + + ea64 * k4 + ea65 * k5 + else + z₆ = α61 * z₁ + α62 * z₂ + tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + nlsolver.c = c6 + nlsolver.tmp = tmp + + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + if integrator.f isa SplitFunction + z₇ = z₂ + u = nlsolver.tmp + γ * z₆ + k6 = dt * f2(u, p, t + c6 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + ea71 * k1 + + ea73 * k3 + ea74 * k4 + ea75 * k5 + ea76 * k6 + else + z₇ = α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ + tmp = uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + end + nlsolver.z = z₇ + nlsolver.c = c7 + nlsolver.tmp = tmp + + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + if integrator.f isa SplitFunction + z₈ = z₅ + u = nlsolver.tmp + γ * z₇ + k7 = dt * f2(u, p, t + c7 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + ea81 * k1 + + ea83 * k3 + ea84 * k4 + ea85 * k5 + ea86 * k6 + ea87 * k7 + else + z₈ = α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ + tmp = uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + end + nlsolver.z = z₈ + nlsolver.c = 1 + nlsolver.tmp = tmp + + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₈ + if integrator.f isa SplitFunction + k8 = dt * f2(u, p, t + dt) + integrator.stats.nf2 += 1 + u = uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + γ * z₈ + + eb1 * k1 + eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 + eb8 * k8 + end + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + tmp = btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + + btilde8 * z₈ + ebtilde1 * k1 + ebtilde4 * k4 + ebtilde5 * k5 + + ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 + else + tmp = btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + + btilde8 * z₈ + end + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.k[1] = integrator.fsalfirst + integrator.fsallast = integrator.f(u, p, t + dt) + integrator.k[2] = integrator.fsallast + else + integrator.fsallast = z₈ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + end + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::KenCarp5Cache, repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver, step_limiter! = cache + @unpack k1, k2, k3, k4, k5, k6, k7, k8 = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab + @unpack α31, α32, α41, α42, α51, α52, α61, α62, α71, α72, α73, α74, α75, α81, α82, α83, α84, α85 = cache.tab + @unpack btilde1, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea43, ea51, ea53, ea54, ea61, ea63, ea64, ea65 = cache.tab + @unpack ea71, ea73, ea74, ea75, ea76, ea81, ea83, ea84, ea85, ea86, ea87 = cache.tab + @unpack eb1, eb4, eb5, eb6, eb7, eb8 = cache.tab + @unpack ebtilde1, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + ##### Step 1 + + if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail + # Explicit tableau is not FSAL + # Make this not compute on repeat + f(z₁, integrator.uprev, p, integrator.t) + z₁ .*= dt + else + # FSAL Step 1 + @.. broadcast=false z₁=dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Allow other choices here + copyto!(z₂, z₁) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ + @.. broadcast=false tmp+=ea21 * k1 + end + + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ .= z₂ + @.. broadcast=false u=tmp + γ * z₂ + f2(k2, u, p, t + 2γdt) + k2 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + @.. broadcast=false z₃=a31 * z₁ + α32 * z₂ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ .= z₃ + @.. broadcast=false u=tmp + γ * z₃ + f2(k3, u, p, t + c3 * dt) + k3 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a41 * z₁ + a43 * z₃ + ea41 * k1 + ea43 * k3 + else + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + @.. broadcast=false tmp=uprev + a41 * z₁ + a43 * z₃ + end + nlsolver.z = z₄ + + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ .= z₂ + @.. broadcast=false u=tmp + γ * z₄ + f2(k4, u, p, t + c4 * dt) + k4 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ + ea51 * k1 + + ea53 * k3 + ea54 * k4 + else + @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ + @.. broadcast=false tmp=uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ .= z₃ + @.. broadcast=false u=tmp + γ * z₅ + f2(k5, u, p, t + c5 * dt) + k5 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + + ea61 * k1 + ea63 * k3 + ea64 * k4 + ea65 * k5 + else + @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + if integrator.f isa SplitFunction + z₇ .= z₂ + @.. broadcast=false u=tmp + γ * z₆ + f2(k6, u, p, t + c6 * dt) + k6 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + ea71 * k1 + ea73 * k3 + ea74 * k4 + ea75 * k5 + + ea76 * k6 + else + @.. broadcast=false z₇=α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ + @.. broadcast=false tmp=uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + end + nlsolver.z = z₇ + + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + if integrator.f isa SplitFunction + z₈ .= z₅ + @.. broadcast=false u=tmp + γ * z₇ + f2(k7, u, p, t + c7 * dt) + k7 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + + a87 * z₇ + ea81 * k1 + ea83 * k3 + ea84 * k4 + ea85 * k5 + + ea86 * k6 + ea87 * k7 + else + @.. broadcast=false z₈=α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ + @.. broadcast=false tmp=uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + end + nlsolver.z = z₈ + + nlsolver.c = 1 + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₈ + if integrator.f isa SplitFunction + f2(k8, u, p, t + dt) + k8 .*= dt + integrator.stats.nf += 1 + @.. broadcast=false u=uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + + γ * z₈ + eb1 * k1 + eb4 * k4 + eb5 * k5 + eb6 * k6 + + eb7 * k7 + eb8 * k8 + end + + step_limiter!(u, integrator, p, t + dt) + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + @.. broadcast=false tmp=btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + + ebtilde1 * k1 + ebtilde4 * k4 + ebtilde5 * k5 + + ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 + else + @.. broadcast=false tmp=btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + end + + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.f(integrator.fsallast, u, p, t + dt) + else + @.. broadcast=false integrator.fsallast=z₈ / dt + end +end + +@muladd function perform_step!(integrator, cache::KenCarp47ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab + @unpack α31, α32, α41, α42, α43, α51, α52, α61, α62, α63, α71, α72, α73, α74, α75, α76 = cache.tab + @unpack btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76 = cache.tab + @unpack eb3, eb4, eb5, eb6, eb7 = cache.tab + @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + ##### Step 1 + + if integrator.f isa SplitFunction + # Explicit tableau is not FSAL + # Make this not compute on repeat + z₁ = dt .* f(uprev, p, t) + else + # FSAL Step 1 + z₁ = dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = z₁ + + tmp = uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + k1 = dt * integrator.fsalfirst - z₁ + tmp += ea21 * k1 + end + nlsolver.tmp = tmp + nlsolver.c = 2γ + + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ = z₂ + u = nlsolver.tmp + γ * z₂ + k2 = dt * f2(u, p, t + 2γdt) + integrator.stats.nf2 += 1 + tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + z₃ = α31 * z₁ + α32 * z₂ + tmp = uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + nlsolver.tmp = tmp + nlsolver.c = c3 + + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ = z₃ + u = nlsolver.tmp + γ * z₃ + k3 = dt * f2(u, p, t + c3 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 + else + z₄ = α41 * z₁ + α42 * z₂ + α43 * z₃ + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + nlsolver.tmp = tmp + nlsolver.c = c4 + + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ = z₁ + u = nlsolver.tmp + γ * z₄ + k4 = dt * f2(u, p, t + c4 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea52 * k2 + + ea53 * k3 + ea54 * k4 + else + z₅ = α51 * z₁ + α52 * z₂ + tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + nlsolver.tmp = tmp + nlsolver.c = c5 + + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ = z₃ + u = nlsolver.tmp + γ * z₅ + k5 = dt * f2(u, p, t + c5 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + + ea62 * k2 + ea63 * k3 + ea64 * k4 + ea65 * k5 + else + z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ + tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + nlsolver.tmp = tmp + nlsolver.c = c6 + + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + if integrator.f isa SplitFunction + z₇ = z₆ + u = nlsolver.tmp + γ * z₆ + k6 = dt * f2(u, p, t + c6 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + ea71 * k1 + ea72 * k2 + + ea73 * k3 + ea74 * k4 + ea75 * k5 + ea76 * k6 + else + z₇ = α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ + +α76 * z₆ + tmp = uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + end + nlsolver.z = z₇ + nlsolver.c = 1 + nlsolver.tmp = tmp + + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₇ + if integrator.f isa SplitFunction + k7 = dt * f2(u, p, t + dt) + u = uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + γ * z₇ + eb3 * k3 + + eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 + end + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + + ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + ebtilde6 * k6 + + ebtilde7 * k7 + else + tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + end + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.k[1] = integrator.fsalfirst + integrator.fsallast = integrator.f(u, p, t + dt) + integrator.k[2] = integrator.fsallast + else + integrator.fsallast = z₇ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + end + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::KenCarp47Cache, repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver = cache + @unpack k1, k2, k3, k4, k5, k6, k7 = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab + @unpack α31, α32, α41, α42, α43, α51, α52, α61, α62, α63, α71, α72, α73, α74, α75, α76 = cache.tab + @unpack btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76 = cache.tab + @unpack eb3, eb4, eb5, eb6, eb7 = cache.tab + @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + ##### Step 1 + + if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail + # Explicit tableau is not FSAL + # Make this not compute on repeat + f(z₁, integrator.uprev, p, integrator.t) + z₁ .*= dt + else + # FSAL Step 1 + @.. broadcast=false z₁=dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Allow other choices here + z₂ .= z₁ + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ + @.. broadcast=false tmp+=ea21 * k1 + end + + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ .= z₂ + @.. broadcast=false u=tmp + γ * z₂ + f2(k2, u, p, t + 2γdt) + k2 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + #Guess is from Hermite derivative on z₁ and z₂ + @.. broadcast=false z₃=a31 * z₁ + α32 * z₂ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ .= z₃ + @.. broadcast=false u=tmp + γ * z₃ + f2(k3, u, p, t + c3 * dt) + k3 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + + ea42 * k2 + ea43 * k3 + else + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + α43 * z₃ + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ .= z₁ + @.. broadcast=false u=tmp + γ * z₄ + f2(k4, u, p, t + c4 * dt) + k4 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + + ea51 * k1 + ea52 * k2 + ea53 * k3 + ea54 * k4 + else + @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ .= z₃ + @.. broadcast=false u=tmp + γ * z₅ + f2(k5, u, p, t + c5 * dt) + k5 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + + a65 * z₅ + ea61 * k1 + ea62 * k2 + ea63 * k3 + ea64 * k4 + + ea65 * k5 + else + @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + if integrator.f isa SplitFunction + z₇ .= z₆ + @.. broadcast=false u=tmp + γ * z₆ + f2(k6, u, p, t + c6 * dt) + k6 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + + ea71 * k1 + ea72 * k2 + ea73 * k3 + ea74 * k4 + ea75 * k5 + + ea76 * k6 + else + @.. broadcast=false z₇=α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ + + α76 * z₆ + @.. broadcast=false tmp=uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + end + nlsolver.z = z₇ + + nlsolver.c = 1 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₇ + if integrator.f isa SplitFunction + f2(k7, u, p, t + dt) + k7 .*= dt + integrator.stats.nf += 1 + @.. broadcast=false u=uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + γ * z₇ + + eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 + end + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + ebtilde3 * k3 + + ebtilde4 * k4 + ebtilde5 * k5 + ebtilde6 * k6 + + ebtilde7 * k7 + else + @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + end + + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.f(integrator.fsallast, u, p, t + dt) + else + @.. broadcast=false integrator.fsallast=z₇ / dt + end +end + +@muladd function perform_step!(integrator, cache::KenCarp58ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + nlsolver = cache.nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a83, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab + @unpack α31, α32, α41, α42, α51, α52, α61, α62, α63, α71, α72, α73, α81, α82, α83, α84, α85, α86, α87 = cache.tab + @unpack btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab + @unpack ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, ea85, ea86, ea87 = cache.tab + @unpack eb3, eb4, eb5, eb6, eb7, eb8 = cache.tab + @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + # calculate W + markfirststage!(nlsolver) + + ##### Step 1 + + if integrator.f isa SplitFunction + # Explicit tableau is not FSAL + # Make this not compute on repeat + z₁ = dt .* f(uprev, p, t) + else + # FSAL Step 1 + z₁ = dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Add extrapolation choice + + nlsolver.z = z₂ = z₁ + + tmp = uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + k1 = dt * integrator.fsalfirst - z₁ + tmp += ea21 * k1 + end + nlsolver.tmp = tmp + nlsolver.c = 2γ + + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ = z₂ + u = nlsolver.tmp + γ * z₂ + k2 = dt * f2(u, p, t + 2γdt) + integrator.stats.nf2 += 1 + tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + z₃ = α31 * z₁ + α32 * z₂ + tmp = uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + nlsolver.c = c3 + nlsolver.tmp = tmp + + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ = z₁ + u = nlsolver.tmp + γ * z₃ + k3 = dt * f2(u, p, t + c3 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 + else + z₄ = α41 * z₁ + α42 * z₂ + tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + nlsolver.c = c4 + nlsolver.tmp = tmp + + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ = z₂ + u = nlsolver.tmp + γ * z₄ + k4 = dt * f2(u, p, t + c4 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea52 * k2 + + ea53 * k3 + ea54 * k4 + else + z₅ = α51 * z₁ + α52 * z₂ + tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + nlsolver.c = c5 + nlsolver.tmp = tmp + + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ = z₃ + u = nlsolver.tmp + γ * z₅ + k5 = dt * f2(u, p, t + c5 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + + ea62 * k2 + ea63 * k3 + ea64 * k4 + ea65 * k5 + else + z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ + tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + nlsolver.c = c6 + nlsolver.tmp = tmp + + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + if integrator.f isa SplitFunction + z₇ = z₃ + u = nlsolver.tmp + γ * z₆ + k6 = dt * f2(u, p, t + c6 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + + ea71 * k1 + ea72 * k2 + ea73 * k3 + ea74 * k4 + ea75 * k5 + ea76 * k6 + else + z₇ = α71 * z₁ + α72 * z₂ + α73 * z₃ + tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + end + nlsolver.z = z₇ + nlsolver.c = c7 + nlsolver.tmp = tmp + + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + if integrator.f isa SplitFunction + z₈ = z₇ + u = nlsolver.tmp + γ * z₇ + k7 = dt * f2(u, p, t + c7 * dt) + integrator.stats.nf2 += 1 + tmp = uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + ea81 * k1 + + ea82 * k2 + ea83 * k3 + ea84 * k4 + ea85 * k5 + ea86 * k6 + ea87 * k7 + else + z₈ = α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ + α86 * z₆ + α87 * z₇ + tmp = uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + end + nlsolver.z = z₈ + nlsolver.c = 1 + nlsolver.tmp = tmp + + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₈ + if integrator.f isa SplitFunction + k8 = dt * f2(u, p, t + dt) + integrator.stats.nf2 += 1 + u = uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + γ * z₈ + + eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 + eb8 * k8 + end + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + + btilde8 * z₈ + ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + + ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 + else + tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + + btilde8 * z₈ + end + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.k[1] = integrator.fsalfirst + integrator.fsallast = integrator.f(u, p, t + dt) + integrator.k[2] = integrator.fsallast + else + integrator.fsallast = z₈ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + end + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::KenCarp58Cache, repeat_step = false) + @unpack t, dt, uprev, u, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver = cache + @unpack k1, k2, k3, k4, k5, k6, k7, k8 = cache + @unpack tmp = nlsolver + @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a83, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab + @unpack α31, α32, α41, α42, α51, α52, α61, α62, α63, α71, α72, α73, α81, α82, α83, α84, α85, α86, α87 = cache.tab + @unpack btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab + @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab + @unpack ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, ea85, ea86, ea87 = cache.tab + @unpack eb3, eb4, eb5, eb6, eb7, eb8 = cache.tab + @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab + alg = unwrap_alg(integrator, true) + + if integrator.f isa SplitFunction + f = integrator.f.f1 + f2 = integrator.f.f2 + else + f = integrator.f + end + + # precalculations + γdt = γ * dt + + markfirststage!(nlsolver) + + ##### Step 1 + + if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail + # Explicit tableau is not FSAL + # Make this not compute on repeat + f(z₁, integrator.uprev, p, integrator.t) + z₁ .*= dt + else + # FSAL Step 1 + @.. broadcast=false z₁=dt * integrator.fsalfirst + end + + ##### Step 2 + + # TODO: Allow other choices here + z₂ .= z₁ + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + + if integrator.f isa SplitFunction + # This assumes the implicit part is cheaper than the explicit part + @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ + @.. broadcast=false tmp+=ea21 * k1 + end + + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + if integrator.f isa SplitFunction + z₃ .= z₂ + @.. broadcast=false u=tmp + γ * z₂ + f2(k2, u, p, t + 2γdt) + k2 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 + else + # Guess is from Hermite derivative on z₁ and z₂ + @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + end + nlsolver.z = z₃ + + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + if integrator.f isa SplitFunction + z₄ .= z₁ + @.. broadcast=false u=tmp + γ * z₃ + f2(k3, u, p, t + c3 * dt) + k3 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + + ea42 * k2 + ea43 * k3 + else + @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + end + nlsolver.z = z₄ + + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + if integrator.f isa SplitFunction + z₅ .= z₂ + @.. broadcast=false u=tmp + γ * z₄ + f2(k4, u, p, t + c4 * dt) + k4 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + + ea51 * k1 + ea52 * k2 + ea53 * k3 + ea54 * k4 + else + @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + end + nlsolver.z = z₅ + + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + if integrator.f isa SplitFunction + z₆ .= z₃ + @.. broadcast=false u=tmp + γ * z₅ + f2(k5, u, p, t + c5 * dt) + k5 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + + a65 * z₅ + ea61 * k1 + ea62 * k2 + ea63 * k3 + ea64 * k4 + + ea65 * k5 + else + @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + end + nlsolver.z = z₆ + + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + if integrator.f isa SplitFunction + z₇ .= z₃ + @.. broadcast=false u=tmp + γ * z₆ + f2(k6, u, p, t + c6 * dt) + k6 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + + a75 * z₅ + a76 * z₆ + ea71 * k1 + ea72 * k2 + ea73 * k3 + + ea74 * k4 + ea75 * k5 + ea76 * k6 + else + @.. broadcast=false z₇=α71 * z₁ + α72 * z₂ + α73 * z₃ + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + + a75 * z₅ + a76 * z₆ + end + nlsolver.z = z₇ + + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + if integrator.f isa SplitFunction + z₈ .= z₇ + @.. broadcast=false u=tmp + γ * z₇ + f2(k7, u, p, t + c7 * dt) + k7 .*= dt + integrator.stats.nf2 += 1 + @.. broadcast=false tmp=uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + + a87 * z₇ + ea81 * k1 + ea82 * k2 + ea83 * k3 + ea84 * k4 + + ea85 * k5 + ea86 * k6 + ea87 * k7 + else + @.. broadcast=false z₈=α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ + + α86 * z₆ + α87 * z₇ + @.. broadcast=false tmp=uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + end + nlsolver.z = z₈ + + nlsolver.c = 1 + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₈ + if integrator.f isa SplitFunction + f2(k8, u, p, t + dt) + k8 .*= dt + integrator.stats.nf += 1 + @.. broadcast=false u=uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + + γ * z₈ + eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + + eb7 * k7 + eb8 * k8 + end + + ################################### Finalize + + if integrator.opts.adaptive + if integrator.f isa SplitFunction + @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + + ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + + ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 + else + @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + end + + if isnewton(nlsolver) && alg.smooth_est # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.f isa SplitFunction + integrator.f(integrator.fsallast, u, p, t + dt) + else + @.. broadcast=false integrator.fsallast=z₈ / dt + end +end diff --git a/src/perform_step/low_order_rk_perform_step.jl b/src/perform_step/low_order_rk_perform_step.jl new file mode 100644 index 0000000000..8b8a0f63dd --- /dev/null +++ b/src/perform_step/low_order_rk_perform_step.jl @@ -0,0 +1,2326 @@ +function initialize!(integrator, cache::BS3ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::BS3ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4 = cache + k1 = integrator.fsalfirst + a1 = dt * a21 + k2 = f(uprev + a1 * k1, p, t + c1 * dt) + a2 = dt * a32 + k3 = f(uprev + a2 * k2, p, t + c2 * dt) + u = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(u, p, t + dt) + integrator.fsallast = k4 + integrator.stats.nf += 3 + if integrator.opts.adaptive + utilde = dt * (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::BS3Cache) + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.fsalfirst = cache.fsalfirst # done by pointers, no copying + integrator.fsallast = cache.k4 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::BS3Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack k2, k3, k4, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4 = cache.tab + # k1 = cache.fsalfirst + k1 = integrator.fsalfirst + a1 = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a1 * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + a2 = dt * a32 + @.. broadcast=false thread=thread tmp=uprev + a2 * k2 + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread u=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k4, u, p, t + dt) + integrator.stats.nf += 3 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde2 * k2 + + btilde3 * k3 + btilde4 * k4) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end +end + +function initialize!(integrator, cache::OwrenZen3ConstantCache) + integrator.kshortsize = 4 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::OwrenZen3ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3 = cache + k1 = integrator.fsalfirst + a1 = dt * a21 + k2 = f(uprev + a1 * k1, p, t + c1 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c2 * dt) + u = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(u, p, t + dt) + integrator.fsallast = k4 + integrator.stats.nf += 3 + if integrator.opts.adaptive + utilde = dt * (btilde1 * k1 + btilde2 * k2 + btilde3 * k3) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.u = u +end + +function initialize!(integrator, cache::OwrenZen3Cache) + integrator.kshortsize = 4 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k4 # setup pointers + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::OwrenZen3Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack k1, k2, k3, k4, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3 = cache.tab + a1 = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a1 * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread u=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k4, u, p, t + dt) + integrator.stats.nf += 3 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde2 * k2 + + btilde3 * k3) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end +end + +function initialize!(integrator, cache::OwrenZen4ConstantCache) + integrator.kshortsize = 6 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::OwrenZen4ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, btilde5 = cache + k1 = integrator.fsalfirst + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + u = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(u, p, t + dt) + integrator.fsallast = k6 + integrator.stats.nf += 5 + if integrator.opts.adaptive + utilde = dt * (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.u = u +end + +function initialize!(integrator, cache::OwrenZen4Cache) + integrator.kshortsize = 6 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k6 # setup pointers + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::OwrenZen4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack k1, k2, k3, k4, k5, k6, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, btilde5 = cache.tab + a = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k6, u, p, t + dt) + integrator.stats.nf += 5 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + + btilde4 * k4 + + btilde5 * k5) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + return nothing +end + +#= +@muladd function perform_step!(integrator, cache::OwrenZen4Cache, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + uidx = eachindex(integrator.uprev) + @unpack k1,k2,k3,k4,k5,k6,utilde,tmp,atmp = cache + @unpack a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a63,a64,a65,c1,c2,c3,c4,btilde1,btilde3,btilde4,btilde5 = cache.tab + a = dt*a21 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2, tmp, p, t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3, tmp, p, t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) + end + f(k4, tmp, p, t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5, tmp, p, t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds u[i] = uprev[i]+dt*(a61*k1[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6, u, p, t+dt) + integrator.stats.nf += 5 + if integrator.opts.adaptive + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i]) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + integrator.EEst = integrator.opts.internalnorm(atmp,t) + end +end +=# + +function initialize!(integrator, cache::OwrenZen5ConstantCache) + integrator.kshortsize = 8 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::OwrenZen5ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache + k1 = integrator.fsalfirst + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, + t + c5 * dt) + k7 = f(uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), + p, t + c6 * dt) + u = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) + k8 = f(u, p, t + dt) + integrator.fsallast = k8 + integrator.stats.nf += 7 + if integrator.opts.adaptive + utilde = dt * + (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.k[8] = k8 + integrator.u = u +end + +function initialize!(integrator, cache::OwrenZen5Cache) + integrator.kshortsize = 8 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.k[8] = cache.k8 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k8 # setup pointers + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::OwrenZen5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + a = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + k3) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k6, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + + a75 * k5 + + a76 * k6) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k7, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + + a86 * k6 + a87 * k7) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k8, u, p, t + dt) + integrator.stats.nf += 7 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + return nothing +end + +#= +@muladd function perform_step!(integrator, cache::OwrenZen5Cache, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + uidx = eachindex(integrator.uprev) + @unpack k1,k2,k3,k4,k5,k6,k7,k8,utilde,tmp,atmp = cache + @unpack a21,a31,a32,a41,a42,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,c1,c2,c3,c4,c5,c6,btilde1,btilde3,btilde4,btilde5,btilde6,btilde7 = cache.tab + a = dt*a21 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2, tmp, p, t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3, tmp, p, t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+k3[i]) + end + f(k4, tmp, p, t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5, tmp, p, t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6, tmp, p, t+c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) + end + f(k7, tmp, p, t+c6*dt) + @tight_loop_macros for i in uidx + @inbounds u[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) + end + f(k8, u, p, t+dt) + integrator.stats.nf += 7 + if integrator.opts.adaptive + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i] + btilde6*k6[i] + btilde7*k7[i]) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + integrator.EEst = integrator.opts.internalnorm(atmp,t) + end +end +=# + +function initialize!(integrator, cache::BS5ConstantCache) + alg = unwrap_alg(integrator, false) + alg.lazy ? (integrator.kshortsize = 8) : (integrator.kshortsize = 11) + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:7 + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast + + if !alg.lazy + @inbounds for i in 9:11 + integrator.k[i] = zero(integrator.fsalfirst) + end + end +end + +@muladd function perform_step!(integrator, cache::BS5ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache + k1 = integrator.fsalfirst + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, + t + c5 * dt) + k7 = f(uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), + p, t + dt) + integrator.stats.nf += 6 + u = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) + integrator.fsallast = f(u, p, t + dt) + k8 = integrator.fsallast + integrator.stats.nf += 1 + if integrator.opts.adaptive + uhat = dt * (bhat1 * k1 + bhat3 * k3 + bhat4 * k4 + bhat5 * k5 + bhat6 * k6) + utilde = dt * + (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7 + btilde8 * k8) + atmp = calculate_residuals(uhat, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + EEst1 = integrator.opts.internalnorm(atmp, t) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + EEst2 = integrator.opts.internalnorm(atmp, t) + integrator.EEst = max(EEst1, EEst2) + end + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.k[8] = k8 + integrator.u = u + + alg = unwrap_alg(integrator, false) + if !alg.lazy && (integrator.opts.adaptive == false || + accept_step_controller(integrator, integrator.opts.controller)) + @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache + k = integrator.k + k[9] = f( + uprev + + dt * (a91 * k[1] + a92 * k[2] + a93 * k[3] + a94 * k[4] + a95 * k[5] + + a96 * k[6] + a97 * k[7] + a98 * k[8]), + p, + t + c6 * dt) + k[10] = f( + uprev + + dt * + (a101 * k[1] + a102 * k[2] + a103 * k[3] + a104 * k[4] + a105 * k[5] + + a106 * k[6] + a107 * k[7] + a108 * k[8] + a109 * k[9]), + p, + t + c7 * dt) + k[11] = f( + uprev + + dt * + (a111 * k[1] + a112 * k[2] + a113 * k[3] + a114 * k[4] + a115 * k[5] + + a116 * k[6] + a117 * k[7] + a118 * k[8] + a119 * k[9] + a1110 * k[10]), + p, t + c8 * dt) + integrator.stats.nf += 3 + end +end + +function initialize!(integrator, cache::BS5Cache) + alg = unwrap_alg(integrator, false) + alg.lazy ? (integrator.kshortsize = 8) : (integrator.kshortsize = 11) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.k[8] = cache.k8 + + if !alg.lazy + integrator.k[9] = similar(cache.k1) + integrator.k[10] = similar(cache.k1) + integrator.k[11] = similar(cache.k1) + end + + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k8 # setup pointers + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::BS5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab + a = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k6, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + + a75 * k5 + + a76 * k6) + stage_limiter!(tmp, integrator, p, t + dt) + f(k7, tmp, p, t + dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + + a86 * k6 + a87 * k7) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k8, u, p, t + dt) + integrator.stats.nf += 7 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * + (bhat1 * k1 + bhat3 * k3 + bhat4 * k4 + + bhat5 * k5 + + bhat6 * k6) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + EEst1 = integrator.opts.internalnorm(atmp, t) + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7 + + btilde8 * k8) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + EEst2 = integrator.opts.internalnorm(atmp, t) + integrator.EEst = max(EEst1, EEst2) + end + alg = unwrap_alg(integrator, false) + if !alg.lazy && (integrator.opts.adaptive == false || + accept_step_controller(integrator, integrator.opts.controller)) + k = integrator.k + @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache.tab + @.. broadcast=false thread=thread tmp=uprev + + dt * (a91 * k[1] + a92 * k[2] + a93 * k[3] + + a94 * k[4] + + a95 * k[5] + a96 * k[6] + a97 * k[7] + + a98 * k[8]) + f(k[9], tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * + (a101 * k[1] + a102 * k[2] + a103 * k[3] + + a104 * k[4] + + a105 * k[5] + a106 * k[6] + a107 * k[7] + + a108 * k[8] + + a109 * k[9]) + f(k[10], tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * + (a111 * k[1] + a112 * k[2] + a113 * k[3] + + a114 * k[4] + + a115 * k[5] + a116 * k[6] + a117 * k[7] + + a118 * k[8] + + a119 * k[9] + a1110 * k[10]) + f(k[11], tmp, p, t + c8 * dt) + integrator.stats.nf += 3 + end + return nothing +end + +#= +@muladd function perform_step!(integrator, cache::BS5Cache, repeat_step=false) + @unpack t,dt,uprev,u,f,p = integrator + uidx = eachindex(integrator.uprev) + @unpack k1,k2,k3,k4,k5,k6,k7,k8,utilde,tmp,atmp = cache + @unpack c1,c2,c3,c4,c5,a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,bhat1,bhat3,bhat4,bhat5,bhat6,btilde1,btilde3,btilde4,btilde5,btilde6,btilde7,btilde8 = cache.tab + a = dt*a21 + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+a*k1[i] + end + f(k2, tmp, p, t+c1*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) + end + f(k3, tmp, p, t+c2*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) + end + f(k4, tmp, p, t+c3*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) + end + f(k5, tmp, p, t+c4*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) + end + f(k6, tmp, p, t+c5*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) + end + f(k7, tmp, p, t+dt) + @tight_loop_macros for i in uidx + @inbounds u[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) + end + f(k8, u, p, t+dt) + integrator.stats.nf += 7 + if integrator.opts.adaptive + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(bhat1*k1[i] + bhat3*k3[i] + bhat4*k4[i] + bhat5*k5[i] + bhat6*k6[i]) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + EEst1 = integrator.opts.internalnorm(atmp,t) + @tight_loop_macros for i in uidx + @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i] + btilde6*k6[i] + btilde7*k7[i] + btilde8*k8[i]) + end + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) + EEst2 = integrator.opts.internalnorm(atmp,t) + integrator.EEst = max(EEst1,EEst2) + end + + alg = unwrap_alg(integrator, false) + if !alg.lazy && (integrator.opts.adaptive == false || accept_step_controller(integrator, integrator.opts.controller)) + k = integrator.k + @unpack c6,c7,c8,a91,a92,a93,a94,a95,a96,a97,a98,a101,a102,a103,a104,a105,a106,a107,a108,a109,a111,a112,a113,a114,a115,a116,a117,a118,a119,a1110 = cache.tab + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a91*k[1][i]+a92*k[2][i]+a93*k[3][i]+a94*k[4][i]+a95*k[5][i]+a96*k[6][i]+a97*k[7][i]+a98*k[8][i]) + end + f(k[9],tmp,p,t+c6*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a101*k[1][i]+a102*k[2][i]+a103*k[3][i]+a104*k[4][i]+a105*k[5][i]+a106*k[6][i]+a107*k[7][i]+a108*k[8][i]+a109*k[9][i]) + end + f(k[10],tmp,p,t+c7*dt) + @tight_loop_macros for i in uidx + @inbounds tmp[i] = uprev[i]+dt*(a111*k[1][i]+a112*k[2][i]+a113*k[3][i]+a114*k[4][i]+a115*k[5][i]+a116*k[6][i]+a117*k[7][i]+a118*k[8][i]+a119*k[9][i]+a1110*k[10][i]) + end + f(k[11],tmp,p,t+c8*dt) + integrator.stats.nf += 3 + end +end +=# + +function initialize!(integrator, cache::Tsit5ConstantCache) + integrator.kshortsize = 7 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::Tsit5ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 + k1 = integrator.fsalfirst + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + g6 = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(g6, p, t + dt) + u = uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) + integrator.fsallast = f(u, p, t + dt) + k7 = integrator.fsallast + integrator.stats.nf += 6 + if integrator.alg isa CompositeAlgorithm + g7 = u + # Hairer II, page 22 modified to use the Inf norm + integrator.eigen_est = integrator.opts.internalnorm( + maximum(abs.(k7 .- k6) ./ (g7 .- g6)), t) + end + if integrator.opts.adaptive + utilde = dt * + (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + + btilde6 * k6 + btilde7 * k7) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.u = u +end + +function initialize!(integrator, cache::Tsit5Cache) + integrator.kshortsize = 7 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k7 # setup pointers + resize!(integrator.k, integrator.kshortsize) + # Setup k pointers + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + return nothing +end + +@muladd function perform_step!(integrator, cache::Tsit5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 + @unpack k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + a = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, f, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, f, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, f, p, t + c3 * dt) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, f, p, t + c4 * dt) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, f, p, t + dt) + f(k6, tmp, p, t + dt) + @.. broadcast=false thread=thread u=uprev + + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + + a75 * k5 + a76 * k6) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k7, u, p, t + dt) + integrator.stats.nf += 6 + if integrator.alg isa CompositeAlgorithm + g7 = u + g6 = tmp + # Hairer II, page 22 modified to use Inf norm + @.. broadcast=false thread=thread utilde=abs((k7 - k6) / (g7 - g6)) + integrator.eigen_est = integrator.opts.internalnorm(norm(utilde, Inf), t) + end + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde2 * k2 + + btilde3 * k3 + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + return nothing +end + +function initialize!(integrator, cache::DP5ConstantCache) + integrator.kshortsize = 4 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + @inbounds for i in eachindex(integrator.k) + integrator.k[i] = zero(integrator.fsalfirst) + end +end + +@muladd function perform_step!(integrator, cache::DP5ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract DP5ConstantCacheActual T T2 + k1 = integrator.fsalfirst + a = dt * a21 + k2 = f(uprev + a * k1, p, t + c1 * dt) + k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) + k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) + k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) + g6 = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(g6, p, t + dt) + update = a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6 + u = uprev + dt * update + integrator.fsallast = f(u, p, t + dt) + k7 = integrator.fsallast + integrator.stats.nf += 6 + if integrator.alg isa CompositeAlgorithm + g7 = u + # Hairer II, page 22 modified to use the Inf norm + integrator.eigen_est = integrator.opts.internalnorm( + maximum(abs.(k7 .- k6) ./ (g7 .- g6)), t) + end + if integrator.opts.adaptive + utilde = dt * + (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.k[1] = update + bspl = k1 - update + integrator.k[2] = bspl + integrator.k[3] = update - k7 - bspl + integrator.k[4] = d1 * k1 + d3 * k3 + d4 * k4 + d5 * k5 + d6 * k6 + d7 * k7 + integrator.u = u +end + +function initialize!(integrator, cache::DP5Cache) + integrator.kshortsize = 4 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.update + integrator.k[2] = cache.bspl + integrator.k[3] = cache.dense_tmp3 + integrator.k[4] = cache.dense_tmp4 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k7 + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::DP5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + T = constvalue(recursive_unitless_bottom_eltype(u)) + T2 = constvalue(typeof(one(t))) + @OnDemandTableauExtract DP5ConstantCacheActual T T2 + @unpack k1, k2, k3, k4, k5, k6, k7, dense_tmp3, dense_tmp4, update, bspl, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + a = dt * a21 + @.. broadcast=false thread=thread tmp=uprev + a * k1 + stage_limiter!(tmp, integrator, p, t + c1 * dt) + f(k2, tmp, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k3, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k4, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k5, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, integrator, p, t + dt) + f(k6, tmp, p, t + dt) + @.. broadcast=false thread=thread update=a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + + a76 * k6 + @.. broadcast=false thread=thread u=uprev + dt * update + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k7, u, p, t + dt) + integrator.stats.nf += 6 + if integrator.alg isa CompositeAlgorithm + g6 = tmp + g7 = u + # Hairer II, page 22 modified to use Inf norm + @.. broadcast=false thread=thread utilde=abs((k7 - k6) / (g7 - g6)) + integrator.eigen_est = integrator.opts.internalnorm( + norm(utilde, Inf) * oneunit(t), t) + end + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + if integrator.opts.calck + #integrator.k[4] == k5 + @.. broadcast=false thread=thread integrator.k[4]=d1 * k1 + d3 * k3 + d4 * k4 + + d5 * k5 + + d6 * k6 + d7 * k7 + #bspl == k3 + @.. broadcast=false thread=thread bspl=k1 - update + # k6 === integrator.k[3] === k2 + @.. broadcast=false thread=thread integrator.k[3]=update - k7 - bspl + end + return nothing +end + +function initialize!(integrator, cache::RKO65ConstantCache) + integrator.kshortsize = 6 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::RKO65ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack α21, α31, α41, α51, α32, α42, α52, α62, α43, α53, α63, α54, α64, α65, β2, β3, β4, β5, β6, c1, c2, c3, c4, c5, c6 = cache + + #k1=integrator.fsalfirst #f(uprev,p,t) + k1 = f(uprev, p, t + c1 * dt) + k2 = f(uprev + α21 * dt * k1, p, t + c2 * dt) + k3 = f(uprev + α31 * dt * k1 + α32 * dt * k2, p, t + c3 * dt) + k4 = f(uprev + α41 * dt * k1 + α42 * dt * k2 + α43 * dt * k3, p, t + c4 * dt) + k5 = f(uprev + α51 * dt * k1 + α52 * dt * k2 + α53 * dt * k3 + α54 * dt * k4, p, + t + c5 * dt) + k6 = f(uprev + α62 * dt * k2 + α63 * dt * k3 + α64 * dt * k4 + α65 * dt * k5, p, + t + c6 * dt) + u = uprev + dt * (β2 * k2 + β3 * k3 + β4 * k4 + β5 * k5 + β6 * k6) + + integrator.fsallast = f(u, p, t + dt) # For interpolation, then FSAL'd + + integrator.stats.nf += 6 + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.u = u +end + +function initialize!(integrator, cache::RKO65Cache) + @unpack k, fsalfirst = cache + integrator.kshortsize = 6 + resize!(integrator.k, integrator.kshortsize) + + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k6 # setup pointers + + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k6 # setup pointers + + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::RKO65Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tmp, k, k1, k2, k3, k4, k5, k6, stage_limiter!, step_limiter!, thread = cache + @unpack α21, α31, α41, α51, α32, α42, α52, α62, α43, α53, α63, α54, α64, α65, β2, β3, β4, β5, β6, c1, c2, c3, c4, c5, c6 = cache.tab + #println("L221: tmp", tmp) + f(k1, uprev, p, t + c1 * dt) + @.. broadcast=false thread=thread tmp=uprev + α21 * dt * k1 + stage_limiter!(tmp, integrator, p, t + c2 * dt) + #println("L224: tmp/k", tmp, k1) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + α31 * dt * k1 + α32 * dt * k2 + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + α41 * dt * k1 + α42 * dt * k2 + + α43 * dt * k3 + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + α51 * dt * k1 + α52 * dt * k2 + + α53 * dt * k3 + + α54 * dt * k4 + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + α62 * dt * k2 + α63 * dt * k3 + + α64 * dt * k4 + + α65 * dt * k5 + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + + @.. broadcast=false thread=thread u=uprev + + dt * + (β2 * k2 + β3 * k3 + β4 * k4 + β5 * k5 + β6 * k6) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + #println("L238: tmp/u", tmp, u) + integrator.stats.nf += 6 + + #return nothing +end + +function initialize!(integrator, cache::FRK65ConstantCache) + integrator.kshortsize = 9 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::FRK65ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack α21, α31, α41, α51, α61, α71, α81, α91, α32, α43, α53, α63, α73, α83, α54, α64, α74, α84, α94, α65, α75, α85, α95, α76, α86, α96, α87, α97, α98, β1, β7, β8, β1tilde, β4tilde, β5tilde, β6tilde, β7tilde, β8tilde, β9tilde, c2, c3, c4, c5, c6, c7, c8, c9, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11 = cache + alg = unwrap_alg(integrator, false) + ν = alg.omega * dt + νsq = ν^2 + β4 = (d1 + νsq * (d2 + νsq * (d3 + νsq * (d4 + νsq * (d5 + νsq * (d6 + +νsq * d7)))))) / + (1 + + νsq * (d8 + νsq * (d9 + νsq * (d10 + νsq * (d11 + νsq * (d12 + +νsq * d13)))))) + β5 = (e1 + νsq * (e2 + νsq * (e3 + νsq * (e4 + νsq * (e5 + νsq * e6))))) / + (1 + νsq * (e8 + νsq * (e9 + νsq * (e10 + νsq * e11)))) + β6 = (f1 + νsq * (f2 + νsq * (f3 + νsq * (f4 + νsq * (f5 + νsq * f6))))) / + (1 + νsq * (f8 + νsq * (f9 + νsq * (f10 + νsq * f11)))) + + k1 = integrator.fsalfirst + k2 = f(uprev + α21 * dt * k1, p, t + c2 * dt) + k3 = f(uprev + α31 * dt * k1 + α32 * dt * k2, p, t + c3 * dt) + k4 = f(uprev + α41 * dt * k1 + α43 * dt * k3, p, t + c4 * dt) + k5 = f(uprev + α51 * dt * k1 + α53 * dt * k3 + α54 * dt * k4, p, t + c5 * dt) + k6 = f(uprev + α61 * dt * k1 + α63 * dt * k3 + α64 * dt * k4 + α65 * dt * k5, p, + t + c6 * dt) + k7 = f( + uprev + α71 * dt * k1 + α73 * dt * k3 + α74 * dt * k4 + α75 * dt * k5 + + α76 * dt * k6, + p, + t + c7 * dt) + k8 = f( + uprev + α81 * dt * k1 + α83 * dt * k3 + α84 * dt * k4 + α85 * dt * k5 + + α86 * dt * k6 + α87 * dt * k7, + p, + t + c8 * dt) + u = uprev + dt * (β1 * k1 + β4 * k4 + β5 * k5 + β6 * k6 + β7 * k7 + β8 * k8) + integrator.fsallast = f(u, p, t + dt) + k9 = integrator.fsallast + if integrator.opts.adaptive + utilde = dt * + (β1tilde * k1 + β4tilde * k4 + β5tilde * k5 + β6tilde * k6 + β7tilde * k7 + + β8tilde * k8 + β9tilde * k9) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.stats.nf += 8 + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.k[8] = k8 + integrator.k[9] = k9 + integrator.u = u +end + +function initialize!(integrator, cache::FRK65Cache) + integrator.kshortsize = 9 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k9 + + resize!(integrator.k, integrator.kshortsize) + + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.k[8] = cache.k8 + integrator.k[9] = cache.k9 + + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::FRK65Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tmp, k1, k2, k3, k4, k5, k6, k7, k8, k9, utilde, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack α21, α31, α41, α51, α61, α71, α81, α91, α32, α43, α53, α63, α73, α83, α54, α64, α74, α84, α94, α65, α75, α85, α95, α76, α86, α96, α87, α97, α98, β1, β7, β8, β1tilde, β4tilde, β5tilde, β6tilde, β7tilde, β8tilde, β9tilde, c2, c3, c4, c5, c6, c7, c8, c9, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11 = cache.tab + alg = unwrap_alg(integrator, false) + + ν = alg.omega * dt + νsq = ν^2 + β4 = (d1 + νsq * (d2 + νsq * (d3 + νsq * (d4 + νsq * (d5 + νsq * (d6 + +νsq * d7)))))) / + (1 + + νsq * (d8 + νsq * (d9 + νsq * (d10 + νsq * (d11 + νsq * (d12 + +νsq * d13)))))) + β5 = (e1 + νsq * (e2 + νsq * (e3 + νsq * (e4 + νsq * (e5 + νsq * e6))))) / + (1 + νsq * (e8 + νsq * (e9 + νsq * (e10 + νsq * e11)))) + β6 = (f1 + νsq * (f2 + νsq * (f3 + νsq * (f4 + νsq * (f5 + νsq * f6))))) / + (1 + νsq * (f8 + νsq * (f9 + νsq * (f10 + νsq * f11)))) + + @.. broadcast=false thread=thread tmp=uprev + α21 * dt * k1 + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + α31 * dt * k1 + α32 * dt * k2 + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + α41 * dt * k1 + α43 * dt * k3 + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + α51 * dt * k1 + α53 * dt * k3 + + α54 * dt * k4 + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + α61 * dt * k1 + α63 * dt * k3 + + α64 * dt * k4 + + α65 * dt * k5 + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + α71 * dt * k1 + α73 * dt * k3 + + α74 * dt * k4 + + α75 * dt * k5 + α76 * dt * k6 + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + α81 * dt * k1 + α83 * dt * k3 + + α84 * dt * k4 + + α85 * dt * k5 + α86 * dt * k6 + α87 * dt * k7 + stage_limiter!(tmp, integrator, p, t + c8 * dt) + f(k8, tmp, p, t + c8 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (β1 * k1 + β4 * k4 + β5 * k5 + β6 * k6 + β7 * k7 + + β8 * k8) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k9, u, p, t + dt) + + integrator.stats.nf += 8 + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (β1tilde * k1 + β4tilde * k4 + + β5tilde * k5 + + β6tilde * k6 + β7tilde * k7 + + β8tilde * k8 + + β9tilde * k9) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + return nothing +end + +function initialize!(integrator, cache::RKMConstantCache) + integrator.kshortsize = 6 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::RKMConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack α2, α3, α4, α5, α6, β1, β2, β3, β4, β6, c2, c3, c4, c5, c6 = cache + + #k1 = f(uprev, p, t) + k1 = integrator.fsalfirst + k2 = f(uprev + α2 * dt * k1, p, t + c2 * dt) + k3 = f(uprev + α3 * dt * k2, p, t + c3 * dt) + k4 = f(uprev + α4 * dt * k3, p, t + c4 * dt) + k5 = f(uprev + α5 * dt * k4, p, t + c5 * dt) + k6 = f(uprev + α6 * dt * k5, p, t + c6 * dt) + u = uprev + dt * (β1 * k1 + β2 * k2 + β3 * k3 + β4 * k4 + β6 * k6) + + integrator.fsallast = f(u, p, t + dt) #interpolation then FSAL'd + integrator.stats.nf += 6 + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + # integrator.k[1] = integrator.fsalfirst + # integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::RKMCache) + @unpack k, fsalfirst = cache + integrator.kshortsize = 6 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + + integrator.fsalfirst = cache.k1 + integrator.fsallast = zero(integrator.fsalfirst) # setup pointers + + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::RKMCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tmp, fsalfirst, k, k1, k2, k3, k4, k5, k6, stage_limiter!, step_limiter!, thread = cache + @unpack α2, α3, α4, α5, α6, β1, β2, β3, β4, β6, c2, c3, c4, c5, c6 = cache.tab + + @.. broadcast=false thread=thread tmp=uprev + α2 * dt * k1 + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + α3 * dt * k2 + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + α4 * dt * k3 + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + α5 * dt * k4 + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + α6 * dt * k5 + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (β1 * k1 + β2 * k2 + β3 * k3 + β4 * k4 + β6 * k6) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(integrator.fsallast, u, p, t + dt) + integrator.stats.nf += 6 + return nothing +end + +function initialize!(integrator, cache::PSRK4p7q6ConstantCache) + integrator.kshortsize = 6 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = zero(integrator.fsalfirst) + integrator.k[3] = zero(integrator.fsalfirst) + integrator.k[4] = zero(integrator.fsalfirst) + integrator.k[5] = zero(integrator.fsalfirst) + integrator.k[6] = integrator.fsallast +end + +function perform_step!(integrator, cache::PSRK4p7q6ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b2, b3, b4, b5, b6, c2, c3, c4, c5, c6 = cache + + k1 = f(uprev, p, t) + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + k5 = f(tmp, p, t + dt * c5) + tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(tmp, p, t + dt * c6) + u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) + + integrator.stats.nf += 6 + integrator.fsallast = k6 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.u = u +end + +function initialize!(integrator, cache::PSRK4p7q6Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 6 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k6 +end + +function perform_step!(integrator, cache::PSRK4p7q6Cache, repeat_step = false) + @unpack k1, k2, k3, k4, k5, k6, tmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b2, b3, b4, b5, b6, c2, c3, c4, c5, c6 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + f(k1, uprev, p, t) + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + + b6 * k6) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + integrator.stats.nf += 6 + integrator.fsallast = k6 + return nothing +end + +function initialize!(integrator, cache::PSRK3p6q5ConstantCache) + integrator.kshortsize = 5 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = zero(integrator.fsalfirst) + integrator.k[3] = zero(integrator.fsalfirst) + integrator.k[4] = zero(integrator.fsalfirst) + integrator.k[5] = integrator.fsallast +end + +function perform_step!(integrator, cache::PSRK3p6q5ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, b1, b2, b3, b4, b5, c2, c3, c4, c5 = cache + + k1 = f(uprev, p, t) + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + k5 = f(tmp, p, t + dt * c5) + u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5) + + integrator.stats.nf += 5 + integrator.fsallast = k5 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.u = u +end + +function initialize!(integrator, cache::PSRK3p6q5Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 5 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k5 +end + +function perform_step!(integrator, cache::PSRK3p6q5Cache, repeat_step = false) + @unpack k1, k2, k3, k4, k5, tmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, b1, b2, b3, b4, b5, c2, c3, c4, c5 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + f(k1, uprev, p, t) + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + integrator.stats.nf += 5 + integrator.fsallast = k5 + return nothing +end + +function initialize!(integrator, cache::PSRK3p5q4ConstantCache) + integrator.kshortsize = 4 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = zero(integrator.fsalfirst) + integrator.k[3] = zero(integrator.fsalfirst) + integrator.k[4] = integrator.fsallast +end + +function perform_step!(integrator, cache::PSRK3p5q4ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a31, a32, a41, a42, a43, b1, b2, b3, b4, c2, c3, c4 = cache + + k1 = f(uprev, p, t) + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4) + + integrator.fsallast = k4 + integrator.stats.nf += 4 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.u = u +end + +function initialize!(integrator, cache::PSRK3p5q4Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 4 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k4 +end + +function perform_step!(integrator, cache::PSRK3p5q4Cache, repeat_step = false) + @unpack k1, k2, k3, k4, tmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, b1, b2, b3, b4, c2, c3, c4 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + f(k1, uprev, p, t) + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + + integrator.stats.nf += 4 + integrator.fsallast = k4 + return nothing +end + +function initialize!(integrator, cache::MSRK5ConstantCache) + integrator.kshortsize = 9 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.fsallast = zero(integrator.fsalfirst) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +function perform_step!(integrator, cache::MSRK5ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache + + k1 = integrator.fsalfirst + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + tmp = uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) + k5 = f(tmp, p, t + dt * c5) + tmp = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(tmp, p, t + dt * c6) + tmp = uprev + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) + k7 = f(tmp, p, t + dt * c7) + tmp = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) + k8 = f(tmp, p, t + dt * c8) + u = uprev + dt * (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + b8 * k8) + k9 = f(u, p, t + dt) + integrator.fsallast = k9 + integrator.stats.nf += 8 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.k[8] = k8 + integrator.k[9] = k9 + integrator.u = u +end + +function initialize!(integrator, cache::MSRK5Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 9 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.k[8] = cache.k8 + integrator.k[9] = cache.k9 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k9 + + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::MSRK5Cache, repeat_step = false) + @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, tmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + + a76 * k6) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + + a86 * k6 + + a87 * k7) + + stage_limiter!(tmp, integrator, p, t + c8 * dt) + f(k8, tmp, p, t + c8 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + + b8 * k8) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k9, u, p, t + dt) + integrator.stats.nf += 8 + integrator.fsallast = k9 + + return nothing +end + +function initialize!(integrator, cache::MSRK6ConstantCache) + integrator.kshortsize = 9 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.fsallast = zero(integrator.fsalfirst) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +function perform_step!(integrator, cache::MSRK6ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache + + k1 = integrator.fsalfirst + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + tmp = uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) + k5 = f(tmp, p, t + dt * c5) + tmp = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(tmp, p, t + dt * c6) + tmp = uprev + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) + k7 = f(tmp, p, t + dt * c7) + tmp = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) + k8 = f(tmp, p, t + dt * c8) + u = uprev + dt * (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + b8 * k8) + k9 = f(u, p, t + dt) + integrator.fsallast = k9 + integrator.stats.nf += 8 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.k[8] = k8 + integrator.k[9] = k9 + integrator.u = u +end + +function initialize!(integrator, cache::MSRK6Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 9 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.k[8] = cache.k8 + integrator.k[9] = cache.k9 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k9 + + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::MSRK6Cache, repeat_step = false) + @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, tmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + + a76 * k6) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + + a86 * k6 + + a87 * k7) + stage_limiter!(tmp, integrator, p, t + c8 * dt) + f(k8, tmp, p, t + c8 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + + b8 * k8) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k9, u, p, t + dt) + integrator.stats.nf += 8 + integrator.fsallast = k9 + + return nothing +end + +function initialize!(integrator, cache::Stepanov5ConstantCache) + integrator.kshortsize = 7 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.fsallast = zero(integrator.fsalfirst) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +function perform_step!(integrator, cache::Stepanov5ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6 = cache + + k1 = integrator.fsalfirst + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + k5 = f(tmp, p, t + dt * c5) + tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(tmp, p, t + dt * c6) + u = uprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) + k7 = f(u, p, t + dt) + integrator.fsallast = k7 + integrator.stats.nf += 6 + + if integrator.opts.adaptive + @.. broadcast=false utilde=dt * (btilde1 * k1 + btilde2 * k2 + + btilde3 * k3 + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.u = u +end + +function initialize!(integrator, cache::Stepanov5Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 7 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k7 + + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::Stepanov5Cache, repeat_step = false) + @unpack k1, k2, k3, k4, k5, k6, k7, tmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k7, u, p, t + dt) + integrator.stats.nf += 6 + integrator.fsallast = k7 + + if integrator.opts.adaptive + utilde = dt * + (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + + btilde6 * k6 + + btilde7 * k7) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + return nothing +end + +function initialize!(integrator, cache::SIR54ConstantCache) + integrator.kshortsize = 8 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.fsallast = zero(integrator.fsalfirst) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + @inbounds for i in 2:(integrator.kshortsize - 1) + integrator.k[i] = zero(integrator.fsalfirst) + end + integrator.k[integrator.kshortsize] = integrator.fsallast +end + +function perform_step!(integrator, cache::SIR54ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, b1, b2, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6, c7 = cache + + k1 = integrator.fsalfirst + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + k5 = f(tmp, p, t + dt * c5) + tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(tmp, p, t + dt * c6) + tmp = uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) + k7 = f(tmp, p, t + dt * c7) + u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) + k8 = f(u, p, t + dt) + integrator.fsallast = k8 + integrator.stats.nf += 7 + + if integrator.opts.adaptive + utilde = dt * (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.k[8] = k8 + integrator.u = u +end + +function initialize!(integrator, cache::SIR54Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 8 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.k[8] = cache.k8 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k8 + + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::SIR54Cache, repeat_step = false) + @unpack k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, b1, b2, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6, c7 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + + a75 * k5 + a76 * k6) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + + b6 * k6) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + f(k8, u, p, t + dt) + integrator.stats.nf += 7 + integrator.fsallast = k8 + + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * + (btilde1 * k1 + btilde2 * k2 + + btilde3 * k3 + btilde4 * k4 + + btilde5 * k5 + btilde6 * k6 + + btilde7 * k7) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + return nothing +end + +function initialize!(integrator, cache::Alshina2ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function perform_step!(integrator, cache::Alshina2ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, b1, b2, b1tilde, c2 = cache + + k1 = f(uprev, p, t) + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + u = uprev + dt * (b1 * k1 + b2 * k2) + + if integrator.opts.adaptive + utilde = dt * (b1tilde * k1) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.stats.nf += 2 + integrator.fsallast = k2 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.u = u +end + +function initialize!(integrator, cache::Alshina2Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 2 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k2 + + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::Alshina2Cache, repeat_step = false) + @unpack k1, k2, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, b1, b2, b1tilde, c2 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + f(k1, uprev, p, t) + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * integrator.fsalfirst) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + + @.. broadcast=false thread=thread u=uprev + + dt * (b1 * k1 + b2 * k2) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (b1tilde * k1) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + integrator.stats.nf += 2 + integrator.fsallast = k2 + + return nothing +end + +function initialize!(integrator, cache::Alshina3ConstantCache) + integrator.kshortsize = 3 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = zero(integrator.fsalfirst) + integrator.k[3] = integrator.fsallast +end + +function perform_step!(integrator, cache::Alshina3ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a32, b1, b2, b3, b2tilde, c2, c3 = cache + + k1 = f(uprev, p, t) + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3) + + if integrator.opts.adaptive + utilde = dt * (b2tilde * k2) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.stats.nf += 3 + integrator.fsallast = k3 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.u = u +end + +function initialize!(integrator, cache::Alshina3Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 3 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k3 + + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 +end + +function perform_step!(integrator, cache::Alshina3Cache, repeat_step = false) + @unpack k1, k2, k3, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a32, b1, b2, b3, b2tilde, c2, c3 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + f(k1, uprev, p, t) + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * (b1 * k1 + b2 * k2 + b3 * k3) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + if integrator.opts.adaptive + @.. broadcast=false thread=thread utilde=dt * (b2tilde * k2) + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t, + thread) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.stats.nf += 3 + integrator.fsallast = k3 + + return nothing +end + +function initialize!(integrator, cache::Alshina6ConstantCache) + integrator.kshortsize = 7 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = zero(integrator.fsalfirst) + integrator.k[3] = zero(integrator.fsalfirst) + integrator.k[4] = zero(integrator.fsalfirst) + integrator.k[5] = zero(integrator.fsalfirst) + integrator.k[6] = zero(integrator.fsalfirst) + integrator.k[7] = integrator.fsallast +end + +function perform_step!(integrator, cache::Alshina6ConstantCache, repeat_step = false) + @unpack u, uprev, f, p, dt, t = integrator + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, + b1, b5, b6, b7, c2, c3, c4, c5, c6, c7 = cache + + k1 = f(uprev, p, t) + tmp = uprev + dt * (a21 * k1) + k2 = f(tmp, p, t + c2 * dt) + tmp = uprev + dt * (a31 * k1 + a32 * k2) + k3 = f(tmp, p, t + c3 * dt) + tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + k4 = f(tmp, p, t + dt * c4) + tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + k5 = f(tmp, p, t + dt * c5) + tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) + k6 = f(tmp, p, t + dt * c6) + tmp = uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) + k7 = f(tmp, p, t + dt * c7) + + integrator.fsallast = k7 + + u = uprev + dt * (b1 * k1 + b5 * k5 + b6 * k6 + b7 * k7) + + integrator.stats.nf += 7 + + integrator.k[1] = k1 + integrator.k[2] = k2 + integrator.k[3] = k3 + integrator.k[4] = k4 + integrator.k[5] = k5 + integrator.k[6] = k6 + integrator.k[7] = k7 + integrator.u = u +end + +function initialize!(integrator, cache::Alshina6Cache) + @unpack uprev, f, p, t = integrator + + integrator.kshortsize = 7 + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = cache.k1 + integrator.k[2] = cache.k2 + integrator.k[3] = cache.k3 + integrator.k[4] = cache.k4 + integrator.k[5] = cache.k5 + integrator.k[6] = cache.k6 + integrator.k[7] = cache.k7 + integrator.fsalfirst = cache.k1 + integrator.fsallast = cache.k7 +end + +function perform_step!(integrator, cache::Alshina6Cache, repeat_step = false) + @unpack k1, k2, k3, k4, k5, k6, k7, tmp, stage_limiter!, step_limiter!, thread = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, + b1, b5, b6, b7, c2, c3, c4, c5, c6, c7 = cache.tab + @unpack u, uprev, t, dt, f, p = integrator + + f(k1, uprev, p, t) + @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) + stage_limiter!(tmp, integrator, p, t + c2 * dt) + f(k2, tmp, p, t + c2 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) + stage_limiter!(tmp, integrator, p, t + c3 * dt) + f(k3, tmp, p, t + c3 * dt) + @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) + stage_limiter!(tmp, integrator, p, t + c4 * dt) + f(k4, tmp, p, t + c4 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) + stage_limiter!(tmp, integrator, p, t + c5 * dt) + f(k5, tmp, p, t + c5 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + + a65 * k5) + stage_limiter!(tmp, integrator, p, t + c6 * dt) + f(k6, tmp, p, t + c6 * dt) + @.. broadcast=false thread=thread tmp=uprev + + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + + a75 * k5 + a76 * k6) + stage_limiter!(tmp, integrator, p, t + c7 * dt) + f(k7, tmp, p, t + c7 * dt) + @.. broadcast=false thread=thread u=uprev + + dt * + (b1 * k1 + b5 * k5 + b6 * k6 + b7 * k7) + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + integrator.stats.nf += 7 + integrator.fsallast = k7 + return nothing +end diff --git a/src/perform_step/rosenbrock_perform_step.jl b/src/perform_step/rosenbrock_perform_step.jl new file mode 100644 index 0000000000..8cd2ffd1f3 --- /dev/null +++ b/src/perform_step/rosenbrock_perform_step.jl @@ -0,0 +1,1989 @@ +function initialize!(integrator, cache::Union{Rosenbrock23Cache, + Rosenbrock32Cache}) + integrator.kshortsize = 2 + @unpack k₁, k₂, fsalfirst, fsallast = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = fsallast + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = k₁ + integrator.k[2] = k₂ + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 +end + +function initialize!(integrator, + cache::Union{Rosenbrock23ConstantCache, + Rosenbrock32ConstantCache}) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = zero(integrator.fsalfirst) + integrator.k[2] = zero(integrator.fsalfirst) +end + +@muladd function perform_step!(integrator, cache::Rosenbrock23Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p, opts = integrator + @unpack k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, tmp, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache + @unpack c₃₂, d = cache.tab + + # Assignments + sizeu = size(u) + mass_matrix = integrator.f.mass_matrix + + # Precalculations + γ = dt * d + dto2 = dt / 2 + dto6 = dt / 6 + + if repeat_step + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 + end + + calc_rosenbrock_differentiation!(integrator, cache, γ, γ, repeat_step, false) + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + + if repeat_step + linres = dolinsolve( + integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = γ)) + else + linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = γ)) + end + + vecu = _vec(linres.u) + veck₁ = _vec(k₁) + + @.. broadcast=false veck₁=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + dto2 * k₁ + stage_limiter!(u, integrator, p, t + dto2) + f(f₁, u, p, t + dto2) + integrator.stats.nf += 1 + + if mass_matrix === I + copyto!(tmp, k₁) + else + mul!(_vec(tmp), mass_matrix, _vec(k₁)) + end + + @.. broadcast=false linsolve_tmp=f₁ - tmp + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + vecu = _vec(linres.u) + veck2 = _vec(k₂) + + @.. broadcast=false veck2=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false k₂+=k₁ + @.. broadcast=false u=uprev + dt * k₂ + stage_limiter!(u, integrator, p, t + dt) + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + f(fsallast, u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=fsallast - c₃₂ * (k₂ - f₁) - + 2(k₁ - fsalfirst) + dt * dT + else + @.. broadcast=false du2=c₃₂ * k₂ + 2k₁ + mul!(_vec(du1), mass_matrix, _vec(du2)) + @.. broadcast=false linsolve_tmp=fsallast - du1 + c₃₂ * f₁ + 2fsalfirst + + dt * dT + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + vecu = _vec(linres.u) + veck3 = _vec(k₃) + @.. broadcast=false veck3=-vecu + + integrator.stats.nsolve += 1 + + if mass_matrix === I + @.. broadcast=false tmp=dto6 * (k₁ - 2 * k₂ + k₃) + else + veck₁ = _vec(k₁) + veck₂ = _vec(k₂) + veck₃ = _vec(k₃) + vectmp = _vec(tmp) + @.. broadcast=false vectmp=ifelse(cache.algebraic_vars, + false, dto6 * (veck₁ - 2 * veck₂ + veck₃)) + end + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + + if mass_matrix !== I + algvar = reshape(cache.algebraic_vars, size(u)) + @.. broadcast=false atmp=ifelse(algvar, fsallast, false) / + integrator.opts.abstol + integrator.EEst += integrator.opts.internalnorm(atmp, t) + end + end + cache.linsolve = linres.cache +end + +@muladd function perform_step!(integrator, cache::Rosenbrock32Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p, opts = integrator + @unpack k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, tmp, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache + @unpack c₃₂, d = cache.tab + + # Assignments + sizeu = size(u) + mass_matrix = integrator.f.mass_matrix + + # Precalculations + γ = dt * d + dto2 = dt / 2 + dto6 = dt / 6 + + if repeat_step + f(integrator.fsalfirst, uprev, p, t) + integrator.stats.nf += 1 + end + + calc_rosenbrock_differentiation!(integrator, cache, γ, γ, repeat_step, false) + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + + if repeat_step + linres = dolinsolve( + integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = γ)) + else + linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = γ)) + end + + vecu = _vec(linres.u) + veck₁ = _vec(k₁) + + @.. broadcast=false veck₁=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + dto2 * k₁ + stage_limiter!(u, integrator, p, t + dto2) + f(f₁, u, p, t + dto2) + integrator.stats.nf += 1 + + if mass_matrix === I + tmp .= k₁ + else + mul!(_vec(tmp), mass_matrix, _vec(k₁)) + end + + @.. broadcast=false linsolve_tmp=f₁ - tmp + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + vecu = _vec(linres.u) + veck2 = _vec(k₂) + + @.. broadcast=false veck2=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false k₂+=k₁ + @.. broadcast=false tmp=uprev + dt * k₂ + stage_limiter!(u, integrator, p, t + dt) + f(fsallast, tmp, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=fsallast - c₃₂ * (k₂ - f₁) - 2(k₁ - fsalfirst) + + dt * dT + else + @.. broadcast=false du2=c₃₂ * k₂ + 2k₁ + mul!(_vec(du1), mass_matrix, _vec(du2)) + @.. broadcast=false linsolve_tmp=fsallast - du1 + c₃₂ * f₁ + 2fsalfirst + dt * dT + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + vecu = _vec(linres.u) + veck3 = _vec(k₃) + + @.. broadcast=false veck3=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + dto6 * (k₁ + 4k₂ + k₃) + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + @.. broadcast=false tmp=dto6 * (k₁ - 2 * k₂ + k₃) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + + if mass_matrix !== I + @.. broadcast=false atmp=ifelse(cache.algebraic_vars, fsallast, false) / + integrator.opts.abstol + integrator.EEst += integrator.opts.internalnorm(atmp, t) + end + end + cache.linsolve = linres.cache +end + +@muladd function perform_step!(integrator, cache::Rosenbrock23ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack c₃₂, d, tf, uf = cache + + # Precalculations + γ = dt * d + dto2 = dt / 2 + dto6 = dt / 6 + + if repeat_step + integrator.fsalfirst = f(uprev, p, t) + integrator.stats.nf += 1 + end + + mass_matrix = integrator.f.mass_matrix + + # Time derivative + dT = calc_tderivative(integrator, cache) + + W = calc_W(integrator, cache, γ, repeat_step) + if !issuccess_W(W) + integrator.EEst = 2 + return nothing + end + + k₁ = _reshape(W \ -_vec((integrator.fsalfirst + γ * dT)), axes(uprev)) + integrator.stats.nsolve += 1 + f₁ = f(uprev + dto2 * k₁, p, t + dto2) + integrator.stats.nf += 1 + + if mass_matrix === I + k₂ = _reshape(W \ -_vec(f₁ - k₁), axes(uprev)) + k₁ + else + k₂ = _reshape(W \ -_vec(f₁ - mass_matrix * k₁), axes(uprev)) + k₁ + end + integrator.stats.nsolve += 1 + u = uprev + dt * k₂ + + if integrator.opts.adaptive + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + k₃ = _reshape( + W \ + -_vec((integrator.fsallast - c₃₂ * (k₂ - f₁) - + 2 * (k₁ - integrator.fsalfirst) + dt * dT)), + axes(uprev)) + else + linsolve_tmp = integrator.fsallast - mass_matrix * (c₃₂ * k₂ + 2 * k₁) + + c₃₂ * f₁ + 2 * integrator.fsalfirst + dt * dT + k₃ = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + end + integrator.stats.nsolve += 1 + + if u isa Number + utilde = dto6 * f.mass_matrix[1, 1] * (k₁ - 2 * k₂ + k₃) + else + utilde = dto6 * f.mass_matrix * (k₁ - 2 * k₂ + k₃) + end + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + + if mass_matrix !== I + atmp = @. ifelse(!integrator.differential_vars, integrator.fsallast, false) ./ + integrator.opts.abstol + integrator.EEst += integrator.opts.internalnorm(atmp, t) + end + end + integrator.k[1] = k₁ + integrator.k[2] = k₂ + integrator.u = u + return nothing +end + +@muladd function perform_step!(integrator, cache::Rosenbrock32ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack c₃₂, d, tf, uf = cache + + # Precalculations + γ = dt * d + dto2 = dt / 2 + dto6 = dt / 6 + + mass_matrix = integrator.f.mass_matrix + + if repeat_step + integrator.fsalfirst = f(uprev, p, t) + integrator.stats.nf += 1 + end + + # Time derivative + dT = calc_tderivative(integrator, cache) + + W = calc_W(integrator, cache, γ, repeat_step) + if !issuccess_W(W) + integrator.EEst = 2 + return nothing + end + + k₁ = _reshape(W \ -_vec((integrator.fsalfirst + γ * dT)), axes(uprev)) + integrator.stats.nsolve += 1 + f₁ = f(uprev + dto2 * k₁, p, t + dto2) + integrator.stats.nf += 1 + + if mass_matrix === I + k₂ = _reshape(W \ -_vec(f₁ - k₁), axes(uprev)) + k₁ + else + linsolve_tmp = f₁ - mass_matrix * k₁ + k₂ = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + k₁ + end + + integrator.stats.nsolve += 1 + tmp = uprev + dt * k₂ + integrator.fsallast = f(tmp, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + k₃ = _reshape( + W \ + -_vec((integrator.fsallast - c₃₂ * (k₂ - f₁) - + 2(k₁ - integrator.fsalfirst) + dt * dT)), + axes(uprev)) + else + linsolve_tmp = integrator.fsallast - mass_matrix * (c₃₂ * k₂ + 2k₁) + c₃₂ * f₁ + + 2 * integrator.fsalfirst + dt * dT + k₃ = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + end + integrator.stats.nsolve += 1 + u = uprev + dto6 * (k₁ + 4k₂ + k₃) + + if integrator.opts.adaptive + utilde = dto6 * (k₁ - 2k₂ + k₃) + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + + if mass_matrix !== I + atmp = @. ifelse(!integrator.differential_vars, integrator.fsallast, false) ./ + integrator.opts.abstol + integrator.EEst += integrator.opts.internalnorm(atmp, t) + end + end + + integrator.k[1] = k₁ + integrator.k[2] = k₂ + integrator.u = u + return nothing +end + +function initialize!(integrator, + cache::Union{Rosenbrock33ConstantCache, + Rosenbrock34ConstantCache, + Rosenbrock4ConstantCache}) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function initialize!(integrator, + cache::Union{Rosenbrock33Cache, + Rosenbrock34Cache, + Rosenbrock4Cache}) + integrator.kshortsize = 2 + @unpack fsalfirst, fsallast = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = fsallast + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = fsalfirst + integrator.k[2] = fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::Rosenbrock33ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tf, uf = cache + @unpack a21, a31, a32, C21, C31, C32, b1, b2, b3, btilde1, btilde2, btilde3, gamma, c2, c3, d1, d2, d3 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtgamma = dt * gamma + + mass_matrix = integrator.f.mass_matrix + + # Time derivative + dT = calc_tderivative(integrator, cache) + + W = calc_W(integrator, cache, dtgamma, repeat_step, true) + if !issuccess_W(W) + integrator.EEst = 2 + return nothing + end + + linsolve_tmp = integrator.fsalfirst + dtd1 * dT + + k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a21 * k1 + du = f(u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd2 * dT + dtC21 * k1 + else + linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) + end + + k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a31 * k1 + a32 * k2 + du = f(u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 + else + linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) + end + + k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + b1 * k1 + b2 * k2 + b3 * k3 + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + + if integrator.opts.adaptive + utilde = btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return nothing +end + +@muladd function perform_step!(integrator, cache::Rosenbrock33Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack du, du1, du2, fsalfirst, fsallast, k1, k2, k3, dT, J, W, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache + @unpack a21, a31, a32, C21, C31, C32, b1, b2, b3, btilde1, btilde2, btilde3, gamma, c2, c3, d1, d2, d3 = cache.tab + + # Assignments + mass_matrix = integrator.f.mass_matrix + sizeu = size(u) + utilde = du + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtgamma = dt * gamma + + calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + + if repeat_step + linres = dolinsolve( + integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + else + linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + end + + vecu = _vec(linres.u) + veck1 = _vec(k1) + + @.. broadcast=false veck1=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a21 * k1 + stage_limiter!(u, integrator, p, t + c2 * dt) + f(du, u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + vecu = _vec(linres.u) + veck2 = _vec(k2) + + @.. broadcast=false veck2=-vecu + + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 + stage_limiter!(u, integrator, p, t + c3 * dt) + f(du, u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + vecu = _vec(linres.u) + veck3 = _vec(k3) + + @.. broadcast=false veck3=-vecu + + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + b1 * k1 + b2 * k2 + b3 * k3 + + step_limiter!(u, integrator, p, t + dt) + + f(fsallast, u, p, t + dt) + integrator.stats.nf += 1 + + if integrator.opts.adaptive + @.. broadcast=false utilde=btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + cache.linsolve = linres.cache +end + +################################################################################ + +@muladd function perform_step!(integrator, cache::Rosenbrock34ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tf, uf = cache + @unpack a21, a31, a32, a41, a42, a43, C21, C31, C32, C41, C42, C43, b1, b2, b3, b4, btilde1, btilde2, btilde3, btilde4, gamma, c2, c3, d1, d2, d3, d4 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtgamma = dt * gamma + + mass_matrix = integrator.f.mass_matrix + # Time derivative + tf.u = uprev + dT = calc_tderivative(integrator, cache) + + W = calc_W(integrator, cache, dtgamma, repeat_step, true) + if !issuccess_W(W) + integrator.EEst = 2 + return nothing + end + + linsolve_tmp = integrator.fsalfirst + dtd1 * dT + + k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev # +a21*k1 a21 == 0 + # du = f(u, p, t+c2*dt) c2 == 0 and a21 == 0 => du = f(uprev, p, t) == fsalfirst + + if mass_matrix === I + linsolve_tmp = integrator.fsalfirst + dtd2 * dT + dtC21 * k1 + else + linsolve_tmp = integrator.fsalfirst + dtd2 * dT + mass_matrix * (dtC21 * k1) + end + + k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a31 * k1 + a32 * k2 + du = f(u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 + else + linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) + end + + k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a41 * k1 + a42 * k2 + a43 * k3 + du = f(u, p, t + dt) #-- c4 = 1 + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd4 * dT + dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + else + linsolve_tmp = du + dtd4 * dT + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + end + + k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + + if integrator.opts.adaptive + utilde = btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 + atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return nothing +end + +@muladd function perform_step!(integrator, cache::Rosenbrock34Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack du, du1, du2, fsalfirst, fsallast, k1, k2, k3, k4, dT, J, W, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache + @unpack a21, a31, a32, a41, a42, a43, C21, C31, C32, C41, C42, C43, b1, b2, b3, b4, btilde1, btilde2, btilde3, btilde4, gamma, c2, c3, d1, d2, d3, d4 = cache.tab + + # Assignments + uidx = eachindex(integrator.uprev) + sizeu = size(u) + mass_matrix = integrator.f.mass_matrix + utilde = du + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtgamma = dt * gamma + + calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + + if repeat_step + linres = dolinsolve( + integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + else + linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), + du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + end + + vecu = _vec(linres.u) + veck1 = _vec(k1) + + @.. broadcast=false veck1=-vecu + integrator.stats.nsolve += 1 + + #= + a21 == 0 and c2 == 0 + so du = integrator.fsalfirst! + @.. broadcast=false u = uprev + a21*k1 + + f(du, u, p, t+c2*dt) + =# + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=fsalfirst + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=fsalfirst + dtd2 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck2 = _vec(k2) + @.. broadcast=false veck2=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 + stage_limiter!(u, integrator, p, t + c3 * dt) + f(du, u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck3 = _vec(k3) + @.. broadcast=false veck3=-vecu + integrator.stats.nsolve += 1 + @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 + stage_limiter!(u, integrator, p, t + dt) + f(du, u, p, t + dt) #-- c4 = 1 + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + dtC41 * k1 + dtC42 * k2 + + dtC43 * k3 + else + @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck4 = _vec(k4) + @.. broadcast=false veck4=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + + step_limiter!(u, integrator, p, t + dt) + + f(fsallast, u, p, t + dt) + integrator.stats.nf += 1 + + if integrator.opts.adaptive + @.. broadcast=false utilde=btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 + calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + cache.linsolve = linres.cache +end + +################################################################################ + +#### ROS2 type method + +@ROS2(:init) +@ROS2(:performstep) + +################################################################################ + +#### ROS23 type method + +@ROS23(:init) +@ROS23(:performstep) + +################################################################################ + +#### ROS34PW type method + +@ROS34PW(:init) +@ROS34PW(:performstep) + +################################################################################ + +#### ROS4 type method + +@Rosenbrock4(:performstep) + +################################################################################ + +#### Rodas3P type method + +function initialize!(integrator, cache::Union{Rodas23WConstantCache, Rodas3PConstantCache}) + integrator.kshortsize = 3 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + # Avoid undefined entries if k is an array of arrays + integrator.k[1] = zero(integrator.u) + integrator.k[2] = zero(integrator.u) + integrator.k[3] = zero(integrator.u) +end + +@muladd function perform_step!( + integrator, cache::Union{Rodas23WConstantCache, Rodas3PConstantCache}, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tf, uf = cache + @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtgamma = dt * gamma + + mass_matrix = integrator.f.mass_matrix + + # Time derivative + tf.u = uprev + dT = calc_tderivative(integrator, cache) + + W = calc_W(integrator, cache, dtgamma, repeat_step, true) + if !issuccess_W(W) + integrator.EEst = 2 + return nothing + end + + du = f(uprev, p, t) + integrator.stats.nf += 1 + k3 = copy(du) #-- save for stage 3 + + linsolve_tmp = du + dtd1 * dT + + k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a21 * k1 + du = f(u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd2 * dT + dtC21 * k1 + else + linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) + end + + k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + + if mass_matrix === I + linsolve_tmp = k3 + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + else + linsolve_tmp = k3 + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) + end + + k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a41 * k1 + a42 * k2 + a43 * k3 + du = f(u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + linsolve_tmp = du + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + end + + k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + + if mass_matrix === I + linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + else + linsolve_tmp = du + + mass_matrix * (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + end + + k5 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + du = u + k4 #-- solution p=2 + u = u + k5 #-- solution p=3 + + EEst = 0.0 + if integrator.opts.calck + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab + integrator.k[1] = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + integrator.k[2] = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + integrator.k[3] = h2_21 * k1 + h2_22 * k2 + h2_23 * k3 + h2_24 * k4 + h2_25 * k5 + if integrator.opts.adaptive + if isa(linsolve_tmp, AbstractFloat) + u_int, u_diff = calculate_interpoldiff( + uprev, du, u, integrator.k[1], integrator.k[2], integrator.k[3]) + else + u_int = linsolve_tmp + u_diff = linsolve_tmp .+ 0 + calculate_interpoldiff!(u_int, u_diff, uprev, du, u, integrator.k[1], + integrator.k[2], integrator.k[3]) + end + atmp = calculate_residuals(u_diff, uprev, u_int, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) #-- role of t unclear + end + end + + if (integrator.alg isa Rodas23W) + k1 = u .+ 0 + u = du .+ 0 + du = k1 .+ 0 + if integrator.opts.calck + integrator.k[1] = integrator.k[3] .+ 0 + integrator.k[2] = 0 * integrator.k[2] + end + end + + if integrator.opts.adaptive + atmp = calculate_residuals(u - du, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) + end + + integrator.u = u + return nothing +end + +function initialize!(integrator, cache::Union{Rodas23WCache, Rodas3PCache}) + integrator.kshortsize = 3 + @unpack dense1, dense2, dense3 = cache + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = dense1 + integrator.k[2] = dense2 + integrator.k[3] = dense3 +end + +@muladd function perform_step!( + integrator, cache::Union{Rodas23WCache, Rodas3PCache}, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack du, du1, du2, dT, J, W, uf, tf, k1, k2, k3, k4, k5, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache + @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab + + # Assignments + sizeu = size(u) + uidx = eachindex(integrator.uprev) + mass_matrix = integrator.f.mass_matrix + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtgamma = dt * gamma + + f(cache.fsalfirst, uprev, p, t) # used in calc_rosenbrock_differentiation! + integrator.stats.nf += 1 + + calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + + if repeat_step + linres = dolinsolve( + integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), + du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + else + linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), + du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + end + + @.. broadcast=false $(_vec(k1))=-linres.u + + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a21 * k1 + stage_limiter!(u, integrator, p, t + c2 * dt) + f(du, u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k2))=-linres.u + integrator.stats.nsolve += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=cache.fsalfirst + dtd3 * dT + + (dtC31 * k1 + dtC32 * k2) + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=cache.fsalfirst + dtd3 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k3))=-linres.u + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 + stage_limiter!(u, integrator, p, t + c2 * dt) + f(du, u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k4))=-linres.u + integrator.stats.nsolve += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + else + @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k5))=-linres.u + integrator.stats.nsolve += 1 + + du = u + k4 #-- p=2 solution + u .+= k5 + + step_limiter!(u, integrator, p, t + dt) + + EEst = 0.0 + if integrator.opts.calck + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab + @.. broadcast=false integrator.k[1]=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + + h25 * k5 + @.. broadcast=false integrator.k[2]=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + + h35 * k5 + @.. broadcast=false integrator.k[3]=h2_21 * k1 + h2_22 * k2 + h2_23 * k3 + + h2_24 * k4 + h2_25 * k5 + if integrator.opts.adaptive + calculate_interpoldiff!( + du1, du2, uprev, du, u, integrator.k[1], integrator.k[2], integrator.k[3]) + calculate_residuals!(atmp, du2, uprev, du1, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) #-- role of t unclear + end + end + + if (integrator.alg isa Rodas23W) + du1[:] = u[:] + u[:] = du[:] + du[:] = du1[:] + if integrator.opts.calck + integrator.k[1][:] = integrator.k[3][:] + integrator.k[2][:] .= 0.0 + end + end + + if integrator.opts.adaptive + calculate_residuals!(atmp, u - du, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) + end + cache.linsolve = linres.cache +end + +function calculate_interpoldiff(uprev, up2, up3, c_koeff, d_koeff, c2_koeff) + u_int = 0.0 + u_diff = 0.0 + a1 = up3 + c_koeff - up2 - c2_koeff + a2 = d_koeff - c_koeff + c2_koeff + a3 = -d_koeff + dis = a2^2 - 3 * a1 * a3 + u_int = up3 + u_diff = 0.0 + if dis > 0.0 #-- Min/Max occurs + tau1 = (-a2 - sqrt(dis)) / (3 * a3) + tau2 = (-a2 + sqrt(dis)) / (3 * a3) + if tau1 > tau2 + tau1, tau2 = tau2, tau1 + end + for tau in (tau1, tau2) + if (tau > 0.0) && (tau < 1.0) + y_tau = (1 - tau) * uprev + + tau * (up3 + (1 - tau) * (c_koeff + tau * d_koeff)) + dy_tau = ((a3 * tau + a2) * tau + a1) * tau + if abs(dy_tau) > abs(u_diff) + u_diff = dy_tau + u_int = y_tau + end + end + end + end + return u_int, u_diff +end + +function calculate_interpoldiff!(u_int, u_diff, uprev, up2, up3, c_koeff, d_koeff, c2_koeff) + for i in eachindex(up2) + a1 = up3[i] + c_koeff[i] - up2[i] - c2_koeff[i] + a2 = d_koeff[i] - c_koeff[i] + c2_koeff[i] + a3 = -d_koeff[i] + dis = a2^2 - 3 * a1 * a3 + u_int[i] = up3[i] + u_diff[i] = 0.0 + if dis > 0.0 #-- Min/Max occurs + tau1 = (-a2 - sqrt(dis)) / (3 * a3) + tau2 = (-a2 + sqrt(dis)) / (3 * a3) + if tau1 > tau2 + tau1, tau2 = tau2, tau1 + end + for tau in (tau1, tau2) + if (tau > 0.0) && (tau < 1.0) + y_tau = (1 - tau) * uprev[i] + + tau * (up3[i] + (1 - tau) * (c_koeff[i] + tau * d_koeff[i])) + dy_tau = ((a3 * tau + a2) * tau + a1) * tau + if abs(dy_tau) > abs(u_diff[i]) + u_diff[i] = dy_tau + u_int[i] = y_tau + end + end + end + end + end +end + +#### Rodas4 type method + +function initialize!(integrator, cache::Rodas4ConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + # Avoid undefined entries if k is an array of arrays + integrator.k[1] = zero(integrator.u) + integrator.k[2] = zero(integrator.u) +end + +@muladd function perform_step!(integrator, cache::Rodas4ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tf, uf = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtgamma = dt * gamma + + mass_matrix = integrator.f.mass_matrix + + # Time derivative + tf.u = uprev + dT = calc_tderivative(integrator, cache) + + W = calc_W(integrator, cache, dtgamma, repeat_step, true) + if !issuccess_W(W) + integrator.EEst = 2 + return nothing + end + + du = f(uprev, p, t) + integrator.stats.nf += 1 + + linsolve_tmp = du + dtd1 * dT + + k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a21 * k1 + du = f(u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd2 * dT + dtC21 * k1 + else + linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) + end + + k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a31 * k1 + a32 * k2 + du = f(u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + else + linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) + end + + k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a41 * k1 + a42 * k2 + a43 * k3 + du = f(u, p, t + c4 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + linsolve_tmp = du + dtd4 * dT + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + end + + k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + du = f(u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + else + linsolve_tmp = du + + mass_matrix * (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + end + + k5 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = u + k5 + du = f(u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + (dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + dtC64 * k4 + dtC63 * k3) + else + linsolve_tmp = du + + mass_matrix * + (dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + dtC64 * k4 + dtC63 * k3) + end + + k6 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = u + k6 + + if integrator.opts.adaptive + atmp = calculate_residuals(k6, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.opts.calck + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab + integrator.k[1] = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + integrator.k[2] = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + end + integrator.u = u + return nothing +end + +function initialize!(integrator, cache::Rodas4Cache) + integrator.kshortsize = 2 + @unpack dense1, dense2 = cache + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = dense1 + integrator.k[2] = dense2 +end + +@muladd function perform_step!(integrator, cache::Rodas4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack du, du1, du2, dT, J, W, uf, tf, k1, k2, k3, k4, k5, k6, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab + + # Assignments + sizeu = size(u) + uidx = eachindex(integrator.uprev) + mass_matrix = integrator.f.mass_matrix + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtgamma = dt * gamma + + f(cache.fsalfirst, uprev, p, t) # used in calc_rosenbrock_differentiation! + integrator.stats.nf += 1 + + calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + + if repeat_step + linres = dolinsolve( + integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), + du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + else + linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), + du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + end + + @.. broadcast=false $(_vec(k1))=-linres.u + + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a21 * k1 + stage_limiter!(u, integrator, p, t + c2 * dt) + f(du, u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k2))=-linres.u + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 + stage_limiter!(u, integrator, p, t + c3 * dt) + f(du, u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k3))=-linres.u + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 + stage_limiter!(u, integrator, p, t + c4 * dt) + f(du, u, p, t + c4 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k4))=-linres.u + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + stage_limiter!(u, integrator, p, t + dt) + f(du, u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + else + @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k5))=-linres.u + integrator.stats.nsolve += 1 + + u .+= k5 + f(du, u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + + dtC64 * k4 + dtC63 * k3) + else + @.. broadcast=false du1=dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + dtC64 * k4 + + dtC63 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + @.. broadcast=false $(_vec(k6))=-linres.u + integrator.stats.nsolve += 1 + + u .+= k6 + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + calculate_residuals!(atmp, k6, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.opts.calck + @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab + @.. broadcast=false integrator.k[1]=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + + h25 * k5 + @.. broadcast=false integrator.k[2]=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + + h35 * k5 + end + cache.linsolve = linres.cache +end + +############################################################################### + +### Rodas5 Method + +function initialize!(integrator, cache::Rosenbrock5ConstantCache) + integrator.kshortsize = 3 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + # Avoid undefined entries if k is an array of arrays + integrator.k[1] = zero(integrator.u) + integrator.k[2] = zero(integrator.u) + integrator.k[3] = zero(integrator.u) +end + +@muladd function perform_step!(integrator, cache::Rosenbrock5ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack tf, uf = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + dtC71 = C71 / dt + dtC72 = C72 / dt + dtC73 = C73 / dt + dtC74 = C74 / dt + dtC75 = C75 / dt + dtC76 = C76 / dt + dtC81 = C81 / dt + dtC82 = C82 / dt + dtC83 = C83 / dt + dtC84 = C84 / dt + dtC85 = C85 / dt + dtC86 = C86 / dt + dtC87 = C87 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtd5 = dt * d5 + dtgamma = dt * gamma + + mass_matrix = integrator.f.mass_matrix + + # Time derivative + dT = calc_tderivative(integrator, cache) + + W = calc_W(integrator, cache, dtgamma, repeat_step, true) + if !issuccess_W(W) + integrator.EEst = 2 + return nothing + end + + du1 = f(uprev, p, t) + integrator.stats.nf += 1 + + linsolve_tmp = du1 + dtd1 * dT + + k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a21 * k1 + du = f(u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd2 * dT + dtC21 * k1 + else + linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) + end + + k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a31 * k1 + a32 * k2 + du = f(u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + else + linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) + end + + k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a41 * k1 + a42 * k2 + a43 * k3 + du = f(u, p, t + c4 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + linsolve_tmp = du + dtd4 * dT + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + end + + k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + du = f(u, p, t + c5 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + dtd5 * dT + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + else + linsolve_tmp = du + dtd5 * dT + + mass_matrix * (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + end + + k5 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 + du = f(u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + dtC65 * k5) + else + linsolve_tmp = du + + mass_matrix * + (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + dtC65 * k5) + end + + k6 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = u + k6 + du = f(u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + + (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + dtC75 * k5 + + dtC76 * k6) + else + linsolve_tmp = du + + mass_matrix * + (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + dtC75 * k5 + + dtC76 * k6) + end + + k7 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = u + k7 + du = f(u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + linsolve_tmp = du + + (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + dtC85 * k5 + + dtC86 * k6 + dtC87 * k7) + else + linsolve_tmp = du + + mass_matrix * + (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + dtC85 * k5 + + dtC86 * k6 + dtC87 * k7) + end + + k8 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + integrator.stats.nsolve += 1 + u = u + k8 + linsolve_tmp = k8 + + if integrator.opts.adaptive + if (integrator.alg isa Rodas5Pe) + linsolve_tmp = 0.2606326497975715 * k1 - 0.005158627295444251 * k2 + + 1.3038988631109731 * k3 + 1.235000722062074 * k4 + + -0.7931985603795049 * k5 - 1.005448461135913 * k6 - + 0.18044626132120234 * k7 + 0.17051519239113755 * k8 + end + atmp = calculate_residuals(linsolve_tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.opts.calck + @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab + integrator.k[1] = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + h26 * k6 + + h27 * k7 + h28 * k8 + integrator.k[2] = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + h36 * k6 + + h37 * k7 + h38 * k8 + integrator.k[3] = h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + h45 * k5 + h46 * k6 + + h47 * k7 + h48 * k8 + if (integrator.alg isa Rodas5Pr) && integrator.opts.adaptive && + (integrator.EEst < 1.0) + k2 = 0.5 * (uprev + u + + 0.5 * (integrator.k[1] + 0.5 * (integrator.k[2] + 0.5 * integrator.k[3]))) + du1 = (0.25 * (integrator.k[2] + integrator.k[3]) - uprev + u) / dt + du = f(k2, p, t + dt / 2) + integrator.stats.nf += 1 + if mass_matrix === I + du2 = du1 - du + else + du2 = mass_matrix * du1 - du + end + EEst = norm(du2) / (integrator.opts.abstol + integrator.opts.reltol * norm(k2)) + integrator.EEst = max(EEst, integrator.EEst) + end + end + + integrator.u = u + return nothing +end + +function initialize!(integrator, cache::Rosenbrock5Cache) + integrator.kshortsize = 3 + @unpack dense1, dense2, dense3 = cache + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = dense1 + integrator.k[2] = dense2 + integrator.k[3] = dense3 +end + +@muladd function perform_step!(integrator, cache::Rosenbrock5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack du, du1, du2, k1, k2, k3, k4, k5, k6, k7, k8, dT, J, W, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache + @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab + + # Assignments + sizeu = size(u) + uidx = eachindex(integrator.uprev) + mass_matrix = integrator.f.mass_matrix + + # Precalculations + dtC21 = C21 / dt + dtC31 = C31 / dt + dtC32 = C32 / dt + dtC41 = C41 / dt + dtC42 = C42 / dt + dtC43 = C43 / dt + dtC51 = C51 / dt + dtC52 = C52 / dt + dtC53 = C53 / dt + dtC54 = C54 / dt + dtC61 = C61 / dt + dtC62 = C62 / dt + dtC63 = C63 / dt + dtC64 = C64 / dt + dtC65 = C65 / dt + dtC71 = C71 / dt + dtC72 = C72 / dt + dtC73 = C73 / dt + dtC74 = C74 / dt + dtC75 = C75 / dt + dtC76 = C76 / dt + dtC81 = C81 / dt + dtC82 = C82 / dt + dtC83 = C83 / dt + dtC84 = C84 / dt + dtC85 = C85 / dt + dtC86 = C86 / dt + dtC87 = C87 / dt + + dtd1 = dt * d1 + dtd2 = dt * d2 + dtd3 = dt * d3 + dtd4 = dt * d4 + dtd5 = dt * d5 + dtgamma = dt * gamma + + f(cache.fsalfirst, uprev, p, t) # used in calc_rosenbrock_differentiation! + integrator.stats.nf += 1 + + calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) + + calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + + if repeat_step + linres = dolinsolve( + integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), + du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + else + linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), + du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, + solverdata = (; gamma = dtgamma)) + end + + vecu = _vec(linres.u) + veck1 = _vec(k1) + + @.. broadcast=false veck1=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a21 * k1 + stage_limiter!(u, integrator, p, t + c2 * dt) + f(du, u, p, t + c2 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 + else + @.. broadcast=false du1=dtC21 * k1 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck2 = _vec(k2) + @.. broadcast=false veck2=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 + stage_limiter!(u, integrator, p, t + c3 * dt) + f(du, u, p, t + c3 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) + else + @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck3 = _vec(k3) + @.. broadcast=false veck3=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 + stage_limiter!(u, integrator, p, t + c4 * dt) + f(du, u, p, t + c4 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) + else + @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck4 = _vec(k4) + @.. broadcast=false veck4=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 + stage_limiter!(u, integrator, p, t + c5 * dt) + f(du, u, p, t + c5 * dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + dtd5 * dT + + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) + else + @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + dtd5 * dT + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck5 = _vec(k5) + @.. broadcast=false veck5=-vecu + integrator.stats.nsolve += 1 + + @.. broadcast=false u=uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 + stage_limiter!(u, integrator, p, t + dt) + f(du, u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + + dtC64 * k4 + dtC65 * k5) + else + @.. broadcast=false du1=dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + + dtC65 * k5 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck6 = _vec(k6) + @.. broadcast=false veck6=-vecu + integrator.stats.nsolve += 1 + + u .+= k6 + stage_limiter!(u, integrator, p, t + dt) + f(du, u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + + dtC74 * k4 + dtC75 * k5 + dtC76 * k6) + else + @.. broadcast=false du1=dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + + dtC75 * k5 + dtC76 * k6 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck7 = _vec(k7) + @.. broadcast=false veck7=-vecu + integrator.stats.nsolve += 1 + + u .+= k7 + f(du, u, p, t + dt) + integrator.stats.nf += 1 + + if mass_matrix === I + @.. broadcast=false linsolve_tmp=du + (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + + dtC84 * k4 + dtC85 * k5 + dtC86 * k6 + dtC87 * k7) + else + @.. broadcast=false du1=dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + + dtC85 * k5 + dtC86 * k6 + dtC87 * k7 + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. broadcast=false linsolve_tmp=du + du2 + end + + linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) + veck8 = _vec(k8) + @.. broadcast=false veck8=-vecu + integrator.stats.nsolve += 1 + + du .= k8 + u .+= k8 + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + if (integrator.alg isa Rodas5Pe) + du = 0.2606326497975715 * k1 - 0.005158627295444251 * k2 + + 1.3038988631109731 * k3 + 1.235000722062074 * k4 + + -0.7931985603795049 * k5 - 1.005448461135913 * k6 - + 0.18044626132120234 * k7 + 0.17051519239113755 * k8 + end + calculate_residuals!(atmp, du, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + if integrator.opts.calck + @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab + @.. broadcast=false integrator.k[1]=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + + h25 * k5 + h26 * k6 + h27 * k7 + h28 * k8 + @.. broadcast=false integrator.k[2]=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + + h35 * k5 + h36 * k6 + h37 * k7 + h38 * k8 + @.. broadcast=false integrator.k[3]=h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + + h45 * k5 + h46 * k6 + h47 * k7 + h48 * k8 + if (integrator.alg isa Rodas5Pr) && integrator.opts.adaptive && + (integrator.EEst < 1.0) + k2 = 0.5 * (uprev + u + + 0.5 * (integrator.k[1] + 0.5 * (integrator.k[2] + 0.5 * integrator.k[3]))) + du1 = (0.25 * (integrator.k[2] + integrator.k[3]) - uprev + u) / dt + f(du, k2, p, t + dt / 2) + integrator.stats.nf += 1 + if mass_matrix === I + du2 = du1 - du + else + mul!(_vec(du2), mass_matrix, _vec(du1)) + du2 = du2 - du + end + EEst = norm(du2) / (integrator.opts.abstol + integrator.opts.reltol * norm(k2)) + integrator.EEst = max(EEst, integrator.EEst) + end + end + cache.linsolve = linres.cache +end + +@RosenbrockW6S4OS(:init) +@RosenbrockW6S4OS(:performstep) diff --git a/src/perform_step/sdirk_perform_step.jl b/src/perform_step/sdirk_perform_step.jl new file mode 100644 index 0000000000..d94bf0085f --- /dev/null +++ b/src/perform_step/sdirk_perform_step.jl @@ -0,0 +1,3154 @@ +function initialize!(integrator, + cache::Union{ImplicitEulerConstantCache, + ImplicitMidpointConstantCache, + TrapezoidConstantCache, + TRBDF2ConstantCache, + SDIRK2ConstantCache, + SDIRK22ConstantCache, + SSPSDIRK2ConstantCache, + Cash4ConstantCache, + Hairer4ConstantCache, + ESDIRK54I8L2SAConstantCache, + ESDIRK436L2SA2ConstantCache, + ESDIRK437L2SAConstantCache, + ESDIRK547L2SA2ConstantCache, + ESDIRK659L2SAConstantCache, + SFSDIRK4ConstantCache, + SFSDIRK5ConstantCache, + SFSDIRK6ConstantCache, + SFSDIRK7ConstantCache, + SFSDIRK8ConstantCache}) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +function initialize!(integrator, + cache::Union{ImplicitEulerCache, + ImplicitMidpointCache, + TrapezoidCache, + TRBDF2Cache, + SDIRK2Cache, + SDIRK22Cache, + SSPSDIRK2Cache, + Cash4Cache, + Hairer4Cache, + ESDIRK54I8L2SACache, + ESDIRK436L2SA2Cache, + ESDIRK437L2SACache, + ESDIRK547L2SA2Cache, + ESDIRK659L2SACache, + SFSDIRK4Cache, + SFSDIRK5Cache, + SFSDIRK6Cache, + SFSDIRK7Cache, + SFSDIRK8Cache}) + integrator.kshortsize = 2 + integrator.fsalfirst = cache.fsalfirst + integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 +end + +@muladd function perform_step!(integrator, cache::ImplicitEulerConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + nlsolver.z = dt * integrator.fsalfirst + else # :constant + nlsolver.z = zero(u) + end + + nlsolver.tmp = uprev + nlsolver.γ = 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = nlsolver.tmp + z + + if integrator.opts.adaptive && integrator.success_iter > 0 + # local truncation error (LTE) bound by dt^2/2*max|y''(t)| + # use 2nd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s + + tmp = r * + integrator.opts.internalnorm.((u - uprev) / dt1 - (uprev - uprev2) / dt2, t) + atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + integrator.EEst = 1 + end + + integrator.fsallast = f(u, p, t + dt) + + if integrator.opts.adaptive && integrator.differential_vars !== nothing + atmp = @. ifelse(!integrator.differential_vars, integrator.fsallast, false) ./ + integrator.opts.abstol + integrator.EEst += integrator.opts.internalnorm(atmp, t) + end + + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::ImplicitEulerCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack atmp, nlsolver, step_limiter! = cache + @unpack z, tmp = nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + @.. broadcast=false z=dt * integrator.fsalfirst + else # :constant + z .= zero(eltype(u)) + end + + nlsolver.tmp .= uprev + nlsolver.γ = 1 + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=uprev + z + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive && integrator.success_iter > 0 + # local truncation error (LTE) bound by dt^2/2*max|y''(t)| + # use 2nd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s + + @.. broadcast=false tmp=r * integrator.opts.internalnorm( + (u - uprev) / dt1 - + (uprev - uprev2) / dt2, t) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + else + integrator.EEst = 1 + end + integrator.stats.nf += 1 + f(integrator.fsallast, u, p, t + dt) + + if integrator.opts.adaptive && integrator.differential_vars !== nothing + @.. broadcast=false atmp=ifelse(cache.algebraic_vars, integrator.fsallast, false) / + integrator.opts.abstol + integrator.EEst += integrator.opts.internalnorm(atmp, t) + end +end + +@muladd function perform_step!(integrator, cache::ImplicitMidpointConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + γ = 1 // 2 + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + nlsolver.z = dt * integrator.fsalfirst + else # :constant + nlsolver.z = zero(u) + end + + nlsolver.tmp = uprev + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = nlsolver.tmp + z + + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::ImplicitMidpointCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack nlsolver, step_limiter! = cache + @unpack z, tmp = nlsolver + mass_matrix = integrator.f.mass_matrix + alg = unwrap_alg(integrator, true) + γ = 1 // 2 + markfirststage!(nlsolver) + + # initial guess + if alg.extrapolant == :linear + @.. broadcast=false z=dt * integrator.fsalfirst + else # :constant + z .= zero(eltype(u)) + end + + nlsolver.tmp = uprev + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=nlsolver.tmp + z + + step_limiter!(u, integrator, p, t + dt) + + integrator.stats.nf += 1 + f(integrator.fsallast, u, p, t + dt) +end + +@muladd function perform_step!(integrator, cache::TrapezoidConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + # precalculations + γ = 1 // 2 + γdt = γ * dt + markfirststage!(nlsolver) + + # initial guess: constant extrapolation + nlsolver.z = uprev + + if f.mass_matrix === I + nlsolver.tmp = @.. broadcast=false uprev * inv(γdt)+integrator.fsalfirst + else + nlsolver.tmp = (f.mass_matrix * uprev) .* inv(γdt) .+ integrator.fsalfirst + end + nlsolver.α = 1 + nlsolver.γ = γ + nlsolver.method = COEFFICIENT_MULTISTEP + u = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + if integrator.opts.adaptive + if integrator.iter > 2 + # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| + # use 3rd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + uprev3 = cache.uprev3 + tprev2 = cache.tprev2 + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + dt3 = (t - tprev) * (t - tprev2) + dt4 = (tprev - tprev2) * (t - tprev2) + dt5 = t + dt - tprev2 + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s + + # tmp = r*abs(((u - uprev)/dt1 - (uprev - uprev2)/dt2) - ((uprev - uprev2)/dt3 - (uprev2 - uprev3)/dt4)/dt5) + DD31 = (u - uprev) / dt1 - (uprev - uprev2) / dt2 + DD30 = (uprev - uprev2) / dt3 - (uprev2 - uprev3) / dt4 + tmp = r * integrator.opts.internalnorm((DD31 - DD30) / dt5, t) + atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, + t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + if integrator.EEst <= 1 + cache.uprev3 = uprev2 + cache.tprev2 = tprev + end + elseif integrator.success_iter > 0 + integrator.EEst = 1 + cache.uprev3 = integrator.uprev2 + cache.tprev2 = integrator.tprev + else + integrator.EEst = 1 + end + end + + integrator.fsallast = f(u, p, t + dt) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::TrapezoidCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack atmp, nlsolver, step_limiter! = cache + @unpack z, tmp = nlsolver + alg = unwrap_alg(integrator, true) + mass_matrix = integrator.f.mass_matrix + + # precalculations + γ = 1 // 2 + γdt = γ * dt + markfirststage!(nlsolver) + + # initial guess: constant extrapolation + @.. broadcast=false z=uprev + invγdt = inv(γdt) + if mass_matrix === I + @.. broadcast=false tmp=uprev * invγdt + integrator.fsalfirst + else + mul!(u, mass_matrix, uprev) + @.. broadcast=false tmp=u * invγdt + integrator.fsalfirst + end + nlsolver.α = 1 + nlsolver.γ = γ + nlsolver.method = COEFFICIENT_MULTISTEP + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=z + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + if integrator.iter > 2 + # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| + # use 3rd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + uprev3 = cache.uprev3 + tprev2 = cache.tprev2 + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + dt3 = (t - tprev) * (t - tprev2) + dt4 = (tprev - tprev2) * (t - tprev2) + dt5 = t + dt - tprev2 + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s + + # @.. broadcast=false tmp = r*abs(((u - uprev)/dt1 - (uprev - uprev2)/dt2) - ((uprev - uprev2)/dt3 - (uprev2 - uprev3)/dt4)/dt5) + @.. broadcast=false tmp=r * integrator.opts.internalnorm( + (((u - uprev) / dt1 - + (uprev - uprev2) / dt2) #DD31 + - + ((uprev - uprev2) / dt3 - + (uprev2 - uprev3) / + dt4)) / + dt5, + t) + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + if integrator.EEst <= 1 + copyto!(cache.uprev3, uprev2) + cache.tprev2 = tprev + end + elseif integrator.success_iter > 0 + integrator.EEst = 1 + copyto!(cache.uprev3, integrator.uprev2) + cache.tprev2 = integrator.tprev + else + integrator.EEst = 1 + end + end + + integrator.stats.nf += 1 + f(integrator.fsallast, u, p, t + dt) +end + +@muladd function perform_step!(integrator, cache::TRBDF2ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, d, ω, btilde1, btilde2, btilde3, α1, α2 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # FSAL + zprev = dt * integrator.fsalfirst + + ##### Solve Trapezoid Step + + # TODO: Add extrapolation + zᵧ = zprev + nlsolver.z = zᵧ + nlsolver.c = γ + + nlsolver.tmp = uprev + d * zprev + zᵧ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve BDF2 Step + + ### Initial Guess From Shampine + z = α1 * zprev + α2 * zᵧ + nlsolver.z = z + nlsolver.c = 1 + + nlsolver.tmp = uprev + ω * zprev + ω * zᵧ + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + d * z + + ################################### Finalize + + if integrator.opts.adaptive + tmp = btilde1 * zprev + btilde2 * zᵧ + btilde3 * z + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::TRBDF2Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack zprev, zᵧ, atmp, nlsolver, step_limiter! = cache + @unpack z, tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + b = nlsolver.ztmp + @unpack γ, d, ω, btilde1, btilde2, btilde3, α1, α2 = cache.tab + alg = unwrap_alg(integrator, true) + + # FSAL + @.. broadcast=false zprev=dt * integrator.fsalfirst + markfirststage!(nlsolver) + + ##### Solve Trapezoid Step + + # TODO: Add extrapolation + @.. broadcast=false zᵧ=zprev + z .= zᵧ + @.. broadcast=false tmp=uprev + d * zprev + nlsolver.c = γ + zᵧ .= nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve BDF2 Step + + ### Initial Guess From Shampine + @.. broadcast=false z=α1 * zprev + α2 * zᵧ + @.. broadcast=false tmp=uprev + ω * zprev + ω * zᵧ + nlsolver.c = 1 + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + d * z + + step_limiter!(u, integrator, p, t + dt) + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * zprev + btilde2 * zᵧ + btilde3 * z + if alg.smooth_est && isnewton(nlsolver) # From Shampine + est = nlsolver.cache.dz + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z / dt +end + +@muladd function perform_step!(integrator, cache::TRBDF2Cache{<:Array}, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack zprev, zᵧ, atmp, nlsolver, step_limiter! = cache + @unpack z, tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + b = nlsolver.ztmp + @unpack γ, d, ω, btilde1, btilde2, btilde3, α1, α2 = cache.tab + alg = unwrap_alg(integrator, true) + + # FSAL + @inbounds @simd ivdep for i in eachindex(u) + zprev[i] = dt * integrator.fsalfirst[i] + end + markfirststage!(nlsolver) + + ##### Solve Trapezoid Step + + # TODO: Add extrapolation + copyto!(zᵧ, zprev) + copyto!(z, zᵧ) + @inbounds @simd ivdep for i in eachindex(u) + tmp[i] = uprev[i] + d * zprev[i] + end + nlsolver.c = γ + zᵧ .= nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve BDF2 Step + + ### Initial Guess From Shampine + @inbounds @simd ivdep for i in eachindex(u) + z[i] = α1 * zprev[i] + α2 * zᵧ[i] + end + @inbounds @simd ivdep for i in eachindex(u) + tmp[i] = uprev[i] + ω * zprev[i] + ω * zᵧ[i] + end + nlsolver.c = 1 + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @inbounds @simd ivdep for i in eachindex(u) + u[i] = tmp[i] + d * z[i] + end + + step_limiter!(u, integrator, p, t + dt) + + ################################### Finalize + + if integrator.opts.adaptive + @inbounds @simd ivdep for i in eachindex(u) + tmp[i] = btilde1 * zprev[i] + btilde2 * zᵧ[i] + btilde3 * z[i] + end + if alg.smooth_est && isnewton(nlsolver) # From Shampine + est = nlsolver.cache.dz + + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @inbounds @simd ivdep for i in eachindex(u) + integrator.fsallast[i] = z[i] / dt + end +end + +@muladd function perform_step!(integrator, cache::SDIRK2ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # initial guess + if integrator.success_iter > 0 && !integrator.reeval_fsal && + alg.extrapolant == :interpolant + current_extrapolant!(u, t + dt, integrator) + z₁ = u - uprev + elseif alg.extrapolant == :linear + z₁ = dt * integrator.fsalfirst + else + z₁ = zero(u) + end + + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ### Initial Guess Is α₁ = c₂/γ, c₂ = 0 => z₂ = α₁z₁ = 0 + z₂ = zero(u) + nlsolver.z = z₂ + nlsolver.tmp = uprev - z₁ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = uprev + z₁ / 2 + z₂ / 2 + + ################################### Finalize + + if integrator.opts.adaptive + tmp = z₁ / 2 - z₂ / 2 + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = f(u, p, t) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SDIRK2Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, atmp, nlsolver, step_limiter! = cache + @unpack tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # initial guess + if integrator.success_iter > 0 && !integrator.reeval_fsal && + alg.extrapolant == :interpolant + current_extrapolant!(u, t + dt, integrator) + @.. broadcast=false z₁=u - uprev + elseif alg.extrapolant == :linear + @.. broadcast=false z₁=dt * integrator.fsalfirst + else + z₁ .= zero(eltype(u)) + end + nlsolver.z = z₁ + + ##### Step 1 + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 2 + + ### Initial Guess Is α₁ = c₂/γ, c₂ = 0 => z₂ = α₁z₁ = 0 + z₂ .= zero(eltype(u)) + nlsolver.z = z₂ + isnewton(nlsolver) && set_new_W!(nlsolver, false) + @.. broadcast=false tmp=uprev - z₁ + nlsolver.tmp = tmp + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=uprev + z₁ / 2 + z₂ / 2 + + step_limiter!(u, integrator, p, t + dt) + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=z₁ / 2 - z₂ / 2 + if alg.smooth_est && isnewton(nlsolver) # From Shampine + est = nlsolver.cache.dz + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.stats.nf += 1 + f(integrator.fsallast, u, p, t) +end + +@muladd function perform_step!(integrator, cache::SDIRK22ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack a, α, β = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + # precalculations + γ = a * dt + γdt = γ * dt + markfirststage!(nlsolver) + + # initial guess + zprev = dt * integrator.fsalfirst + nlsolver.z = zprev + + # first stage + nlsolver.tmp = uprev + γdt * integrator.fsalfirst + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + uprev = α * nlsolver.tmp + β * z + + # final stage + γ = dt + γdt = γ * dt + markfirststage!(nlsolver) + nlsolver.tmp = uprev + γdt * integrator.fsalfirst + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + u = nlsolver.tmp + + if integrator.opts.adaptive + if integrator.iter > 2 + # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| + # use 3rd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + uprev3 = cache.uprev3 + tprev2 = cache.tprev2 + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + dt3 = (t - tprev) * (t - tprev2) + dt4 = (tprev - tprev2) * (t - tprev2) + dt5 = t + dt - tprev2 + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s + + DD31 = (u - uprev) / dt1 - (uprev - uprev2) / dt2 + DD30 = (uprev - uprev2) / dt3 - (uprev2 - uprev3) / dt4 + tmp = r * abs((DD31 - DD30) / dt5) + atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, + t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + if integrator.EEst <= 1 + cache.uprev3 = uprev2 + cache.tprev2 = tprev + end + elseif integrator.success_iter > 0 + integrator.EEst = 1 + cache.uprev3 = integrator.uprev2 + cache.tprev2 = integrator.tprev + else + integrator.EEst = 1 + end + end + + integrator.stats.nf += 2 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SDIRK22Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack atmp, nlsolver, step_limiter! = cache + @unpack z, tmp = nlsolver + @unpack a, α, β = cache.tab + alg = unwrap_alg(integrator, true) + mass_matrix = integrator.f.mass_matrix + + # precalculations + γ = a * dt + γdt = γ * dt + markfirststage!(nlsolver) + + # first stage + @.. broadcast=false z=dt * integrator.fsalfirst + @.. broadcast=false tmp=uprev + γdt * integrator.fsalfirst + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=α * tmp + β * z + + # final stage + γ = dt + γdt = γ * dt + markfirststage!(nlsolver) + @.. broadcast=false tmp=uprev + γdt * integrator.fsalfirst + z = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + @.. broadcast=false u=nlsolver.tmp + + step_limiter!(u, integrator, p, t + dt) + + if integrator.opts.adaptive + if integrator.iter > 2 + # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| + # use 3rd divided differences (DD) a la SPICE and Shampine + + # TODO: check numerical stability + uprev2 = integrator.uprev2 + tprev = integrator.tprev + uprev3 = cache.uprev3 + tprev2 = cache.tprev2 + + dt1 = dt * (t + dt - tprev) + dt2 = (t - tprev) * (t + dt - tprev) + dt3 = (t - tprev) * (t - tprev2) + dt4 = (tprev - tprev2) * (t - tprev2) + dt5 = t + dt - tprev2 + c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) + r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s + + @inbounds for i in eachindex(u) + DD31 = (u[i] - uprev[i]) / dt1 - (uprev[i] - uprev2[i]) / dt2 + DD30 = (uprev[i] - uprev2[i]) / dt3 - (uprev2[i] - uprev3[i]) / dt4 + tmp[i] = r * abs((DD31 - DD30) / dt5) + end + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + if integrator.EEst <= 1 + copyto!(cache.uprev3, uprev2) + cache.tprev2 = tprev + end + elseif integrator.success_iter > 0 + integrator.EEst = 1 + copyto!(cache.uprev3, integrator.uprev2) + cache.tprev2 = integrator.tprev + else + integrator.EEst = 1 + end + end + + integrator.stats.nf += 2 + f(integrator.fsallast, u, p, t + dt) +end + +@muladd function perform_step!(integrator, cache::SSPSDIRK2ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + γ = eltype(u)(1 // 4) + c2 = typeof(t)(3 // 4) + + markfirststage!(nlsolver) + + # initial guess + if integrator.success_iter > 0 && !integrator.reeval_fsal && + alg.extrapolant == :interpolant + current_extrapolant!(u, t + dt, integrator) + z₁ = u - uprev + elseif alg.extrapolant == :linear + z₁ = dt * integrator.fsalfirst + else + z₁ = zero(u) + end + nlsolver.z = z₁ + + ##### Step 1 + + tstep = t + dt + u = uprev + γ * z₁ + + nlsolver.c = 1 + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 2 + + ### Initial Guess Is α₁ = c₂/γ + z₂ = c2 / γ + nlsolver.z = z₂ + + nlsolver.tmp = uprev + z₁ / 2 + nlsolver.c = 1 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + z₂ / 2 + + ################################### Finalize + + integrator.fsallast = f(u, p, t) + integrator.stats.nf += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SSPSDIRK2Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, nlsolver = cache + @unpack tmp = nlsolver + alg = unwrap_alg(integrator, true) + + γ = eltype(u)(1 // 4) + c2 = typeof(t)(3 // 4) + markfirststage!(nlsolver) + + # initial guess + if integrator.success_iter > 0 && !integrator.reeval_fsal && + alg.extrapolant == :interpolant + current_extrapolant!(u, t + dt, integrator) + @.. broadcast=false z₁=u - uprev + elseif alg.extrapolant == :linear + @.. broadcast=false z₁=dt * integrator.fsalfirst + else + z₁ .= zero(eltype(u)) + end + nlsolver.z = z₁ + nlsolver.tmp = uprev + + ##### Step 1 + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 2 + + ### Initial Guess Is α₁ = c₂/γ + @.. broadcast=false z₂=c2 / γ + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + z₁ / 2 + nlsolver.tmp = tmp + isnewton(nlsolver) && set_new_W!(nlsolver, false) + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + z₂ / 2 + + ################################### Finalize + + integrator.stats.nf += 1 + f(integrator.fsallast, u, p, t) +end + +@muladd function perform_step!(integrator, cache::Cash4ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab + @unpack b1hat1, b2hat1, b3hat1, b4hat1, b1hat2, b2hat2, b3hat2, b4hat2 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ = zero(u) + nlsolver.z = z₁ + + nlsolver.c = γ + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ = zero(u) + nlsolver.z = z₂ + + nlsolver.tmp = uprev + a21 * z₁ + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + z₃ = z₁ + nlsolver.z = z₃ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + z₄ = z₃ + nlsolver.z = z₄ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use yhat2 for prediction + z₅ = b1hat2 * z₁ + b2hat2 * z₂ + b3hat2 * z₃ + b4hat2 * z₄ + nlsolver.z = z₅ + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = 1 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₅ + + ################################### Finalize + + if integrator.opts.adaptive + if alg.embedding == 3 + btilde1 = b1hat2 - a51 + btilde2 = b2hat2 - a52 + btilde3 = b3hat2 - a53 + btilde4 = b4hat2 - a54 + btilde5 = -γ + else + btilde1 = b1hat1 - a51 + btilde2 = b2hat1 - a52 + btilde3 = b3hat1 - a53 + btilde4 = b4hat1 - a54 + btilde5 = -γ + end + + tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₅ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::Cash4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, atmp, nlsolver = cache + @unpack tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab + @unpack b1hat1, b2hat1, b3hat1, b4hat1, b1hat2, b2hat2, b3hat2, b4hat2 = cache.tab + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ .= zero(eltype(z₁)) + nlsolver.z = z₁ + nlsolver.c = γ + nlsolver.tmp = uprev + + # initial step of NLNewton iteration + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(z₂)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + a21 * z₁ + nlsolver.tmp = tmp + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + @.. broadcast=false z₃=z₁ + nlsolver.z = z₃ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=z₃ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + @.. broadcast=false z₅=b1hat2 * z₁ + b2hat2 * z₂ + b3hat2 * z₃ + b4hat2 * z₄ + nlsolver.z = z₅ + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = 1 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₅ + + ################################### Finalize + + if integrator.opts.adaptive + if alg.embedding == 3 + btilde1 = b1hat2 - a51 + btilde2 = b2hat2 - a52 + btilde3 = b3hat2 - a53 + btilde4 = b4hat2 - a54 + btilde5 = -γ + else + btilde1 = b1hat1 - a51 + btilde2 = b2hat1 - a52 + btilde3 = b3hat1 - a53 + btilde4 = b4hat1 - a54 + btilde5 = -γ + end + + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + if alg.smooth_est && isnewton(nlsolver) # From Shampine + est = nlsolver.cache.dz + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₅ / dt +end + +@muladd function perform_step!(integrator, cache::SFSDIRK4ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ = zero(u) + nlsolver.z = z₁ + + nlsolver.c = γ + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ = zero(u) + nlsolver.z = z₂ + + nlsolver.tmp = uprev + a21 * z₁ + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + z₃ = z₁ + nlsolver.z = z₃ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + z₄ = z₃ + nlsolver.z = z₄ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Final Step + + u = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + + integrator.fsallast = z₄ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SFSDIRK4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, nlsolver = cache + @unpack tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ .= zero(eltype(z₁)) + nlsolver.z = z₁ + nlsolver.c = γ + nlsolver.tmp = uprev + + # initial step of NLNewton iteration + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(z₂)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + a21 * z₁ + nlsolver.tmp = tmp + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + @.. broadcast=false z₃=z₁ + nlsolver.z = z₃ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=z₃ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + + ################################### Finalize + @.. broadcast=false integrator.fsallast=z₄ / dt +end + +@muladd function perform_step!(integrator, cache::SFSDIRK5ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, c2, c3, c4, c5 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ = zero(u) + nlsolver.z = z₁ + + nlsolver.c = γ + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ = zero(u) + nlsolver.z = z₂ + + nlsolver.tmp = uprev + a21 * z₁ + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + z₃ = z₁ + nlsolver.z = z₃ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + z₄ = z₃ + nlsolver.z = z₄ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + z₅ = z₄ + nlsolver.z = z₅ + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Final Step + + u = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + + integrator.fsallast = z₅ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SFSDIRK5Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, nlsolver = cache + @unpack tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, c2, c3, c4, c5 = cache.tab + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ .= zero(eltype(z₁)) + nlsolver.z = z₁ + nlsolver.c = γ + nlsolver.tmp = uprev + + # initial step of NLNewton iteration + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(z₂)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + a21 * z₁ + nlsolver.tmp = tmp + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + @.. broadcast=false z₃=z₁ + nlsolver.z = z₃ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=z₃ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + @.. broadcast=false z₅=z₄ + nlsolver.z = z₅ + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + ################################### Finalize + @.. broadcast=false u=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + + @.. broadcast=false integrator.fsallast=z₅ / dt +end + +@muladd function perform_step!(integrator, cache::SFSDIRK6ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, c2, c3, c4, c5, c6 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ = zero(u) + nlsolver.z = z₁ + + nlsolver.c = γ + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ = zero(u) + nlsolver.z = z₂ + + nlsolver.tmp = uprev + a21 * z₁ + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + z₃ = z₁ + nlsolver.z = z₃ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + z₄ = z₃ + nlsolver.z = z₄ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + z₅ = z₄ + nlsolver.z = z₅ + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + z₆ = z₅ + nlsolver.z = z₆ + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Final Step + + u = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + + integrator.fsallast = z₆ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SFSDIRK6Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, nlsolver = cache + @unpack tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, c2, c3, c4, c5, c6 = cache.tab + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ .= zero(eltype(z₁)) + nlsolver.z = z₁ + nlsolver.c = γ + nlsolver.tmp = uprev + + # initial step of NLNewton iteration + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(z₂)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + a21 * z₁ + nlsolver.tmp = tmp + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + @.. broadcast=false z₃=z₁ + nlsolver.z = z₃ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=z₃ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + @.. broadcast=false z₅=z₄ + nlsolver.z = z₅ + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + # Use constant z prediction + @.. broadcast=false z₆=z₅ + nlsolver.z = z₆ + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################### Finalize + @.. broadcast=false u=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + + @.. broadcast=false integrator.fsallast=z₆ / dt +end + +@muladd function perform_step!(integrator, cache::SFSDIRK7ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, c2, c3, c4, c5, c6, c7 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ = zero(u) + nlsolver.z = z₁ + + nlsolver.c = γ + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ = zero(u) + nlsolver.z = z₂ + + nlsolver.tmp = uprev + a21 * z₁ + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + z₃ = z₁ + nlsolver.z = z₃ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + z₄ = z₃ + nlsolver.z = z₄ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + z₅ = z₄ + nlsolver.z = z₅ + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + # Use constant z prediction + z₆ = z₅ + nlsolver.z = z₆ + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + # Use constant z prediction + z₇ = z₆ + nlsolver.z = z₇ + + nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Final Step + + u = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + + integrator.fsallast = z₇ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SFSDIRK7Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, nlsolver = cache + @unpack tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, c2, c3, c4, c5, c6, c7 = cache.tab + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ .= zero(eltype(z₁)) + nlsolver.z = z₁ + nlsolver.c = γ + nlsolver.tmp = uprev + + # initial step of NLNewton iteration + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(z₂)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + a21 * z₁ + nlsolver.tmp = tmp + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + @.. broadcast=false z₃=z₁ + nlsolver.z = z₃ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=z₃ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + @.. broadcast=false z₅=z₄ + nlsolver.z = z₅ + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + # Use constant z prediction + @.. broadcast=false z₆=z₅ + nlsolver.z = z₆ + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + # Use constant z prediction + @.. broadcast=false z₇=z₆ + nlsolver.z = z₇ + + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################### Finalize + @.. broadcast=false u=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + + a86 * z₆ + a87 * z₇ + + @.. broadcast=false integrator.fsallast=z₇ / dt +end + +@muladd function perform_step!(integrator, cache::SFSDIRK8ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, a91, a92, a93, a94, a95, a96, a97, a98, c2, c3, c4, c5, c6, c7, c8 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ = zero(u) + nlsolver.z = z₁ + + nlsolver.c = γ + nlsolver.tmp = uprev + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ = zero(u) + nlsolver.z = z₂ + + nlsolver.tmp = uprev + a21 * z₁ + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + z₃ = z₁ + nlsolver.z = z₃ + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + z₄ = z₃ + nlsolver.z = z₄ + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + z₅ = z₄ + nlsolver.z = z₅ + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + # Use constant z prediction + z₆ = z₅ + nlsolver.z = z₆ + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + # Use constant z prediction + z₇ = z₆ + nlsolver.z = z₇ + + nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + # Use constant z prediction + z₈ = z₇ + nlsolver.z = z₈ + + nlsolver.tmp = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + + a87 * z₇ + nlsolver.c = c8 + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Final Step + + u = uprev + a91 * z₁ + a92 * z₂ + a93 * z₃ + a94 * z₄ + a95 * z₅ + a96 * z₆ + a97 * z₇ + + a98 * z₈ + + integrator.fsallast = z₈ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::SFSDIRK8Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, nlsolver = cache + @unpack tmp = nlsolver + W = isnewton(nlsolver) ? get_W(nlsolver) : nothing + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, a91, a92, a93, a94, a95, a96, a97, a98, c2, c3, c4, c5, c6, c7, c8 = cache.tab + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + ##### Step 1 + + # TODO: Add extrapolation for guess + z₁ .= zero(eltype(z₁)) + nlsolver.z = z₁ + nlsolver.c = γ + nlsolver.tmp = uprev + + # initial step of NLNewton iteration + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(z₂)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + a21 * z₁ + nlsolver.tmp = tmp + isnewton(nlsolver) && set_new_W!(nlsolver, false) + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + # Guess starts from z₁ + @.. broadcast=false z₃=z₁ + nlsolver.z = z₃ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=z₃ + nlsolver.z = z₄ + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use constant z prediction + @.. broadcast=false z₅=z₄ + nlsolver.z = z₅ + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + # Use constant z prediction + @.. broadcast=false z₆=z₅ + nlsolver.z = z₆ + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + # Use constant z prediction + @.. broadcast=false z₇=z₆ + nlsolver.z = z₇ + + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + # Use constant z prediction + @.. broadcast=false z₈=z₇ + nlsolver.z = z₈ + + @.. broadcast=false tmp=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + + a86 * z₆ + a87 * z₇ + nlsolver.c = c8 + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################### Finalize + @.. broadcast=false u=uprev + a91 * z₁ + a92 * z₂ + a93 * z₃ + a94 * z₄ + a95 * z₅ + + a96 * z₆ + a97 * z₇ + a98 * z₈ + + @.. broadcast=false integrator.fsallast=z₈ / dt +end + +@muladd function perform_step!(integrator, cache::Hairer4ConstantCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab + @unpack α21, α31, α32, α41, α43 = cache.tab + @unpack bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # TODO: Add extrapolation for guess + z₁ = zero(u) + nlsolver.z, nlsolver.tmp = z₁, uprev + nlsolver.c = γ + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + z₂ = α21 * z₁ + nlsolver.z = z₂ + nlsolver.tmp = uprev + a21 * z₁ + nlsolver.c = c2 + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + z₃ = α31 * z₁ + α32 * z₂ + nlsolver.z = z₃ + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + z₄ = α41 * z₁ + α43 * z₃ + nlsolver.z = z₄ + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use yhat2 for prediction + z₅ = bhat1 * z₁ + bhat2 * z₂ + bhat3 * z₃ + bhat4 * z₄ + nlsolver.z = z₅ + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = 1 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₅ + + ################################### Finalize + + if integrator.opts.adaptive + tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + if isnewton(nlsolver) && alg.smooth_est # From Shampine + integrator.stats.nsolve += 1 + est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) + else + est = tmp + end + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₅ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +@muladd function perform_step!(integrator, cache::Hairer4Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, atmp, nlsolver = cache + @unpack tmp = nlsolver + @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab + @unpack α21, α31, α32, α41, α43 = cache.tab + @unpack bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab + alg = unwrap_alg(integrator, true) + markfirststage!(nlsolver) + + # initial guess + if integrator.success_iter > 0 && !integrator.reeval_fsal && + alg.extrapolant == :interpolant + current_extrapolant!(u, t + dt, integrator) + @.. broadcast=false z₁=u - uprev + elseif alg.extrapolant == :linear + @.. broadcast=false z₁=dt * integrator.fsalfirst + else + z₁ .= zero(eltype(z₁)) + end + nlsolver.z = z₁ + nlsolver.tmp = uprev + + ##### Step 1 + + nlsolver.c = γ + z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ##### Step 2 + + @.. broadcast=false z₂=α21 * z₁ + nlsolver.z = z₂ + @.. broadcast=false tmp=uprev + a21 * z₁ + nlsolver.tmp = tmp + nlsolver.c = c2 + isnewton(nlsolver) && set_new_W!(nlsolver, false) + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ + nlsolver.z = z₃ + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + @.. broadcast=false z₄=α41 * z₁ + α43 * z₃ + nlsolver.z = z₄ + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + # Use yhat prediction + @.. broadcast=false z₅=bhat1 * z₁ + bhat2 * z₂ + bhat3 * z₃ + bhat4 * z₄ + nlsolver.z = z₅ + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = 1 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₅ + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + if alg.smooth_est && isnewton(nlsolver) # From Shampine + est = nlsolver.cache.dz + linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), + linu = _vec(est)) + + integrator.stats.nsolve += 1 + else + est = tmp + end + calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₅ / dt +end + +@muladd function perform_step!(integrator, cache::ESDIRK54I8L2SAConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + a81, a82, a83, a84, a85, a86, a87, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # TODO: Add extrapolation for guess + + ##### Step 1 + + z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = zero(z₁) + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + nlsolver.z = z₃ = zero(z₂) + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = zero(z₃) + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = z₅ = zero(z₄) + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = z₆ = zero(z₅) + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + nlsolver.z = z₇ = zero(z₆) + + nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + nlsolver.z = z₈ = zero(z₇) + + nlsolver.tmp = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + + a87 * z₇ + nlsolver.c = 1 + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₈ + + ################################### Finalize + + if integrator.opts.adaptive + est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₈ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK54I8L2SACache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver = cache + @unpack tmp = nlsolver + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + a81, a82, a83, a84, a85, a86, a87, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + ##### Step 1 + + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(u)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + nlsolver.z = fill!(z₃, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + nlsolver.z = fill!(z₄, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = fill!(z₅, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = fill!(z₆, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + nlsolver.z = fill!(z₇, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + nlsolver.z = fill!(z₈, zero(eltype(u))) + + @.. broadcast=false nlsolver.tmp=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + + a85 * z₅ + a86 * z₆ + a87 * z₇ + nlsolver.c = oneunit(nlsolver.c) + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₈ + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₈ / dt + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK436L2SA2ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + c3, c4, c5, c6, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # TODO: Add extrapolation for guess + + ##### Step 1 + + z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = zero(z₁) + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + nlsolver.z = z₃ = zero(z₂) + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = zero(z₃) + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = z₅ = zero(z₄) + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = z₆ = zero(z₅) + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₆ + + ################################### Finalize + + if integrator.opts.adaptive + est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₆ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK436L2SA2Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver = cache + @unpack tmp = nlsolver + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + c3, c4, c5, c6, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + ##### Step 1 + + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(u)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + nlsolver.z = fill!(z₃, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + nlsolver.z = fill!(z₄, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = fill!(z₅, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = fill!(z₆, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₆ + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + btilde6 * z₆ + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₆ / dt + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK437L2SAConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # TODO: Add extrapolation for guess + + ##### Step 1 + + z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = zero(z₁) + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + nlsolver.z = z₃ = zero(z₂) + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = zero(z₃) + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = z₅ = zero(z₄) + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = z₆ = zero(z₅) + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + nlsolver.z = z₇ = zero(z₆) + + nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₇ + + ################################### Finalize + + if integrator.opts.adaptive + est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₇ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK437L2SACache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver = cache + @unpack tmp = nlsolver + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + ##### Step 1 + + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(u)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + nlsolver.z = fill!(z₃, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + nlsolver.z = fill!(z₄, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = fill!(z₅, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = fill!(z₆, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = fill!(z₇, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₇ + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₇ / dt + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK547L2SA2ConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # TODO: Add extrapolation for guess + + ##### Step 1 + + z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = zero(z₁) + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + nlsolver.z = z₃ = zero(z₂) + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = zero(z₃) + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = z₅ = zero(z₄) + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = z₆ = zero(z₅) + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + nlsolver.z = z₇ = zero(z₆) + + nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₇ + + ################################### Finalize + + if integrator.opts.adaptive + est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₇ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK547L2SA2Cache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver = cache + @unpack tmp = nlsolver + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + ##### Step 1 + + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(u)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + nlsolver.z = fill!(z₃, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + nlsolver.z = fill!(z₄, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = fill!(z₅, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = fill!(z₆, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + nlsolver.z = fill!(z₇, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₇ + + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₇ / dt + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK659L2SAConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + a81, a82, a83, a84, a85, a86, a87, + a94, a95, a96, a97, a98, + c3, c4, c5, c6, c7, c8, c9, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9 = cache.tab + nlsolver = cache.nlsolver + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + # TODO: Add extrapolation for guess + + ##### Step 1 + + z₁ = dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation choice + nlsolver.z = z₂ = zero(z₁) + + nlsolver.tmp = uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 3 + + nlsolver.z = z₃ = zero(z₂) + + nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + nlsolver.z = z₄ = zero(z₃) + + nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = z₅ = zero(z₄) + + nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = z₆ = zero(z₅) + + nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + nlsolver.z = z₇ = zero(z₆) + + nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + nlsolver.z = z₈ = zero(z₇) + + nlsolver.tmp = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + + a87 * z₇ + nlsolver.c = c8 + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 9 + nlsolver.z = z₉ = zero(z₈) + + nlsolver.tmp = uprev + a94 * z₄ + a95 * z₅ + a96 * z₆ + a97 * z₇ + a98 * z₈ + nlsolver.c = c9 + z₉ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + u = nlsolver.tmp + γ * z₉ + + ################################### Finalize + + if integrator.opts.adaptive + est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + btilde9 * z₉ + atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + integrator.fsallast = z₉ ./ dt + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u + return +end + +@muladd function perform_step!(integrator, cache::ESDIRK659L2SACache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, z₉, atmp, nlsolver = cache + @unpack tmp = nlsolver + @unpack γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + a81, a82, a83, a84, a85, a86, a87, + a94, a95, a96, a97, a98, + c3, c4, c5, c6, c7, c8, c9, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9 = cache.tab + alg = unwrap_alg(integrator, true) + + # precalculations + γdt = γ * dt + markfirststage!(nlsolver) + + ##### Step 1 + + @.. broadcast=false z₁=dt * integrator.fsalfirst + + ##### Step 2 + + # TODO: Add extrapolation for guess + z₂ .= zero(eltype(u)) + nlsolver.z = z₂ + + @.. broadcast=false tmp=uprev + γ * z₁ + nlsolver.c = 2γ + z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + isnewton(nlsolver) && set_new_W!(nlsolver, false) + + ################################## Solve Step 3 + + nlsolver.z = fill!(z₃, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + nlsolver.c = c3 + z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 4 + + # Use constant z prediction + nlsolver.z = fill!(z₄, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + nlsolver.c = c4 + z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 5 + + nlsolver.z = fill!(z₅, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + nlsolver.c = c5 + z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 6 + + nlsolver.z = fill!(z₆, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + nlsolver.c = c6 + z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 7 + + nlsolver.z = fill!(z₇, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + + a76 * z₆ + nlsolver.c = c7 + z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 8 + + nlsolver.z = fill!(z₈, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + + a86 * z₆ + a87 * z₇ + nlsolver.c = c8 + z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + ################################## Solve Step 9 + + nlsolver.z = fill!(z₉, zero(eltype(u))) + + @.. broadcast=false tmp=uprev + a94 * z₄ + a95 * z₅ + a96 * z₆ + a97 * z₇ + a98 * z₈ + nlsolver.c = c9 + z₉ = nlsolve!(nlsolver, integrator, cache, repeat_step) + nlsolvefail(nlsolver) && return + + @.. broadcast=false u=tmp + γ * z₉ + ################################### Finalize + + if integrator.opts.adaptive + @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + + btilde5 * z₅ + + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + btilde9 * z₉ + calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, + integrator.opts.reltol, integrator.opts.internalnorm, t) + integrator.EEst = integrator.opts.internalnorm(atmp, t) + end + + @.. broadcast=false integrator.fsallast=z₉ / dt + return +end diff --git a/src/perform_step/split_perform_step.jl b/src/perform_step/split_perform_step.jl new file mode 100644 index 0000000000..80f7a906d7 --- /dev/null +++ b/src/perform_step/split_perform_step.jl @@ -0,0 +1,50 @@ +function initialize!(integrator, cache::SplitEulerConstantCache) + integrator.kshortsize = 2 + integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) + integrator.fsalfirst = integrator.f.f1(integrator.uprev, integrator.p, integrator.t) + + integrator.f.f2(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal + integrator.stats.nf += 1 + integrator.stats.nf2 += 1 + + # Avoid undefined entries if k is an array of arrays + integrator.fsallast = zero(integrator.fsalfirst) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast +end + +@muladd function perform_step!(integrator, cache::SplitEulerConstantCache, + repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + u = @.. broadcast=false uprev+dt * integrator.fsalfirst + integrator.fsallast = f.f1(u, p, t + dt) + f.f2(u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 + integrator.stats.nf2 += 1 + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.u = u +end + +function initialize!(integrator, cache::SplitEulerCache) + integrator.kshortsize = 2 + @unpack k, fsalfirst = cache + integrator.fsalfirst = fsalfirst + integrator.fsallast = k + resize!(integrator.k, integrator.kshortsize) + integrator.k[1] = integrator.fsalfirst + integrator.k[2] = integrator.fsallast + integrator.f.f1(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.f.f2(cache.tmp, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point + integrator.stats.nf += 1 + integrator.stats.nf2 += 1 + integrator.fsalfirst .+= cache.tmp +end + +@muladd function perform_step!(integrator, cache::SplitEulerCache, repeat_step = false) + @unpack t, dt, uprev, u, f, p = integrator + @.. broadcast=false u=uprev + dt * integrator.fsalfirst + f.f1(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point + f.f2(cache.tmp, u, p, t + dt) # For the interpolation, needs k at the updated point + integrator.stats.nf2 += 1 + integrator.stats.nf += 1 + integrator.fsallast .+= cache.tmp +end diff --git a/src/tableaus/firk_tableaus.jl b/src/tableaus/firk_tableaus.jl new file mode 100644 index 0000000000..85db091bb7 --- /dev/null +++ b/src/tableaus/firk_tableaus.jl @@ -0,0 +1,112 @@ +struct RadauIIA3Tableau{T, T2} + T11::T + T12::T + T21::T + T22::T + TI11::T + TI12::T + TI21::T + TI22::T + c1::T2 + c2::T2 + α::T + β::T + e1::T + e2::T +end + +function RadauIIA3Tableau(T, T2) + T11 = T(0.10540925533894596) + T12 = T(-0.29814239699997197) + T21 = T(0.9486832980505138) + T22 = T(0.0) + TI11 = T(0.0) + TI12 = T(1.0540925533894598) + TI21 = T(-3.3541019662496843) + TI22 = T(0.3726779962499649) + c1 = T2(1 / 3) + c2 = T2(1.0) + α = T(2.0) + β = T(-sqrt(2)) + e1 = T(1 / 4) + e2 = T(-1 / 4) + RadauIIA3Tableau{T, T2}(T11, T12, T21, T22, + TI11, TI12, TI21, TI22, + c1, c2, α, β, e1, e2) +end + +struct RadauIIA5Tableau{T, T2} + T11::T + T12::T + T13::T + T21::T + T22::T + T23::T + T31::T + #T32::T = 1 + #T33::T = 0 + TI11::T + TI12::T + TI13::T + TI21::T + TI22::T + TI23::T + TI31::T + TI32::T + TI33::T + c1::T2 + c2::T2 + #c3::T2 = 1 + γ::T + α::T + β::T + e1::T + e2::T + e3::T +end + +# inv(T) * inv(A) * T = [γ 0 0 +# 0 α -β +# 0 β α] +function RadauIIA5Tableau(T, T2) + T11 = convert(T, 9.1232394870892942792e-02) + T12 = convert(T, -0.14125529502095420843e0) + T13 = convert(T, -3.0029194105147424492e-02) + T21 = convert(T, 0.24171793270710701896e0) + T22 = convert(T, 0.20412935229379993199e0) + T23 = convert(T, 0.38294211275726193779e0) + T31 = convert(T, 0.96604818261509293619e0) + TI11 = convert(T, 4.3255798900631553510e0) + TI12 = convert(T, 0.33919925181580986954e0) + TI13 = convert(T, 0.54177053993587487119e0) + TI21 = convert(T, -4.1787185915519047273e0) + TI22 = convert(T, -0.32768282076106238708e0) + TI23 = convert(T, 0.47662355450055045196e0) + TI31 = convert(T, -0.50287263494578687595e0) + TI32 = convert(T, 2.5719269498556054292e0) + TI33 = convert(T, -0.59603920482822492497e0) + + sqrt6 = sqrt(6) + + c1 = convert(T2, (4 - sqrt6) / 10) + c2 = convert(T2, (4 + sqrt6) / 10) + + cbrt9 = cbrt(9) + + γ′ = convert(T, (6.0 + cbrt9 * (cbrt9 - 1)) / 30) # eigval of `A` + α′ = convert(T, (12.0 - cbrt9 * (cbrt9 - 1)) / 60) # eigval of `A` + β′ = convert(T, cbrt9 * (cbrt9 + 1) * sqrt(3) / 60) # eigval of `A` + scale = α′^2 + β′^2 + γ = inv(γ′) # eigval of `inv(A)` + α = α′ / scale # eigval of `inv(A)` + β = β′ / scale # eigval of `inv(A)` + + e1 = convert(T, -(13 + 7 * sqrt6) / 3) + e2 = convert(T, (-13 + 7 * sqrt6) / 3) + e3 = convert(T, -1 / 3) + RadauIIA5Tableau{T, T2}(T11, T12, T13, T21, T22, T23, T31, #= T33 = 0 =# + TI11, TI12, TI13, TI21, TI22, TI23, TI31, TI32, TI33, + c1, c2, #= c3 = 1 =# + γ, α, β, + e1, e2, e3) +end diff --git a/src/tableaus/high_order_rk_tableaus.jl b/src/tableaus/high_order_rk_tableaus.jl new file mode 100644 index 0000000000..1e03a14aac --- /dev/null +++ b/src/tableaus/high_order_rk_tableaus.jl @@ -0,0 +1,1406 @@ +struct TanYam7ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + c1::T2 + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + a21::T + a31::T + a32::T + a41::T + a43::T + a51::T + a53::T + a54::T + a61::T + a63::T + a64::T + a65::T + a71::T + a73::T + a74::T + a75::T + a76::T + a81::T + a83::T + a84::T + a85::T + a86::T + a87::T + a91::T + a93::T + a94::T + a95::T + a96::T + a97::T + a98::T + a101::T + a103::T + a104::T + a105::T + a106::T + a107::T + a108::T + b1::T + b4::T + b5::T + b6::T + b7::T + b8::T + b9::T + btilde1::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + btilde8::T + btilde9::T + btilde10::T +end + +""" +On the Optimization of Some Nine-Stage Seventh-order Runge-Kutta Method, by M. Tanaka, S. Muramatsu and S. Yamashita, +Information Processing Society of Japan, Vol. 33, No. 12 (1992) pages 1512-1526. +""" +function TanYam7ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + c1 = convert(T2, 0.07816646510113846) + c2 = convert(T2, 0.1172496976517077) + c3 = convert(T2, 0.17587454647756157) + c4 = convert(T2, 0.4987401101913988) + c5 = convert(T2, 0.772121690184484) + c6 = convert(T2, 0.9911856696047768) + c7 = convert(T2, 0.9995019582097662) + a21 = convert(T, 0.07816646510113846) + a31 = convert(T, 0.029312424412926925) + a32 = convert(T, 0.08793727323878078) + a41 = convert(T, 0.04396863661939039) + a43 = convert(T, 0.13190590985817116) + a51 = convert(T, 0.7361834837738382) + a53 = convert(T, -2.8337999624233303) + a54 = convert(T, 2.5963565888408913) + a61 = convert(T, -12.062819391370866) + a63 = convert(T, 48.20838100175243) + a64 = convert(T, -38.05863046463434) + a65 = convert(T, 2.6851905444372632) + a71 = convert(T, 105.21957276320198) + a73 = convert(T, -417.92888626241256) + a74 = convert(T, 332.3155504499333) + a75 = convert(T, -19.827591183572938) + a76 = convert(T, 1.2125399024549859) + a81 = convert(T, 114.67755718631742) + a83 = convert(T, -455.5612169896097) + a84 = convert(T, 362.24095553923144) + a85 = convert(T, -21.67190442182809) + a86 = convert(T, 1.3189132007137807) + a87 = convert(T, -0.0048025566150346555) + a91 = convert(T, 115.21334870553768) + a93 = convert(T, -457.69356568613233) + a94 = convert(T, 363.93688218862735) + a95 = convert(T, -21.776682078900294) + a96 = convert(T, 1.3250670887878468) + a97 = convert(T, -0.004518190986768983) + a98 = convert(T, -0.0005320269334859959) + a101 = convert(T, 115.18928245800194) + a103 = convert(T, -457.598022271643) + a104 = convert(T, 363.8610256312148) + a105 = convert(T, -21.77212754027556) + a106 = convert(T, 1.3248804645074317) + a107 = convert(T, -0.0045057252106918315) + a108 = convert(T, -0.0005330165949429136) + b1 = convert(T, 0.05126014249744686) + b4 = convert(T, 0.27521638456212627) + b5 = convert(T, 0.33696650340710543) + b6 = convert(T, 0.18986072244906577) + b7 = convert(T, 8.461099418514403) + b8 = convert(T, -130.15941672640542) + b9 = convert(T, 121.84501355497527) + # bhat1 =convert(T,0.051002417590377186) + # bhat4 =convert(T,0.27613929504666546) + # bhat5 =convert(T,0.333788602069686) + # bhat6 =convert(T,0.20196531139081392) + # bhat7 =convert(T,5.755075459041811) + # bhat8 =convert(T,-85.61797108513936) + # bhat10=convert(T,80) + btilde1 = convert(T, -0.0002577249070696835) + btilde4 = convert(T, 0.0009229104845391819) + btilde5 = convert(T, -0.0031779013374194105) + btilde6 = convert(T, 0.01210458894174817) + btilde7 = convert(T, -2.706023959472591) + btilde8 = convert(T, 44.541445641266066) + btilde9 = convert(T, -121.84501355497527) + btilde10 = convert(T, 80) + + TanYam7ConstantCache( + c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, + a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, + a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, + a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, + btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10) +end + +""" +On the Optimization of Some Nine-Stage Seventh-order Runge-Kutta Method, by M. Tanaka, S. Muramatsu and S. Yamashita, +Information Processing Society of Japan, Vol. 33, No. 12 (1992) pages 1512-1526. +""" +function TanYam7ConstantCache(T::Type, T2::Type) + c1 = convert(T2, 36259 // 463869) + c2 = convert(T2, 36259 // 309246) + c3 = convert(T2, 36259 // 206164) + c4 = convert(T2, 76401 // 153188) + c5 = convert(T2, 5164663400901569152 // 6688924124988083687) + c6 = convert(T2, 3486 // 3517) + c7 = convert(T2, 44151 // 44173) + a21 = convert(T, 36259 // 463869) + a31 = convert(T, 36259 // 1236984) + a32 = convert(T, 36259 // 412328) + a41 = convert(T, 36259 // 824656) + a43 = convert(T, 108777 // 824656) + a51 = convert(T, 17751533712975975593187 // 24112920357813127230992) + a53 = convert(T, -68331192803887602162951 // 24112920357813127230992) + a54 = convert(T, 7825717455900471140481 // 3014115044726640903874) + a61 = convert(T, + -BigInt(2425518501234340256175806929031336393991001205323654593685210322030691047097621496102266496) // + BigInt(201073929944556265242953373967503382318096046559546854970564286270157897072030532387737241)) + a63 = convert(T, + BigInt(126875939114499086848675646731069753055308007638565564293214808307459627250976287910912) // + BigInt(2631823273838775215546306644775636213113650954300949659959480717139276934490785884841)) + a64 = convert(T, + -BigInt(18238165682427587123600563411903599919711680222699338744428834349094610403849667513626245575680) // + BigInt(479212348415302218688412787744011607018072627155280851781784515530195350673833210517995172867)) + a65 = convert(T, + BigInt(74777425357290689294313120787550134201356775453356604582280658347816977407509825814840320) // + BigInt(27848089034948481594251542168496834020714916243735255636715495143105044359669539013058107)) + a71 = convert(T, + BigInt(42210784012026021620512889337138957588173072058924928398799062235) // + BigInt(401168555464694196502745570125544252560955194769351196028554688)) + a73 = convert(T, + -BigInt(53537582181289418572806048482253962781541488) // + BigInt(128102133978061070595749084326726258918069)) + a74 = convert(T, + BigInt(6373437319382536771018620806214785516542915567996760353063349991182871200304) // + BigInt(19178871740288180724887392022898914045213833131528843480576173243533301485)) + a75 = convert(T, + -BigInt(836513109281956728811652083904588515347012294160401579661057793958992) // + BigInt(42189346226535262916910956145917457264775063492307360825161811325023)) + a76 = convert(T, + BigInt(10038768138260655813133796321688310283082351149893792474426644227234755871856831386997923013888351) // + BigInt(8279123943002224665888560854425725483235895533066047643118716510648226939201056966728652698557760)) + a81 = convert(T, + BigInt(1454976871505621321312348899226731229297985195430097820532172928754404221419640982320963761) // + BigInt(12687546780768188413911065021432924447284583965992535848754097389537051103097048673168256)) + a83 = convert(T, + -BigInt(1452249436938195913836212549773886207822959770792) // + BigInt(3187825000852340545619892931005470986913487349)) + a84 = convert(T, + BigInt(3193785703967379485471835519262043520640585789136428552340853315619929163223926155626278646291801931779256) // + BigInt(8816743814108800069900425523882492176796603795861854625575345408990649746129323017714575203134405597571)) + a85 = convert(T, + -BigInt(314398569508916946629277462588835135011587938712337655816458752800894863689255534896547161759213480) // + BigInt(14507196201560052990013371105817112064769849230048646555812475120383456376679192045076337148816813)) + a86 = convert(T, + BigInt(5021633516852870452803558794670341128133410978274753232000155240629688617274518068065484524425884625107263111090060721584249881611265924113) // + BigInt(3807402575192378287101053794016079417728266285278436439472658972755893033722804748992796724254152818232996309281540415603729279478920107136)) + a87 = convert(T, + -BigInt(894451839895008223904010765658125850176064186717638397881061173697811879745) // + BigInt(186244934020117483847289332768639722211239803963523669807238114327710091115676)) + a91 = convert(T, + BigInt(152015786770038627019906826956584678402371493198250158080970494807155603994339) // + BigInt(1319428594672311986480108760138089275639618425553698631283119461253421932416)) + a93 = convert(T, + -BigInt(19887569115365707672105043997835466942389220328) // + BigInt(43451712251082409470704235239058276887205131)) + a94 = convert(T, + BigInt(6298831527954572673520838478029639446424615570453903300371170696118960335541193275024146681623960) // + BigInt(17307483347318198085207889427954666589398911583434527253470846782562794571553580157056644256313)) + a95 = convert(T, + -BigInt(16267621644623777942279856217571823792451732234540266142050307930357537283432611648312520) // + BigInt(747020211145282116967827947968990352912884924402891384654470989583659988117513448655559)) + a96 = convert(T, + BigInt(491920517345271821393960134665582163547632868347911487496995665146055538579545277983570189994492481977206720065882583432234119698425636137169515) // + BigInt(371241970695441505578374965290296000309261530083026613438333515399198575394818137422626328203755084156959422247928840402063855870066548878130304)) + a97 = convert(T, + -BigInt(17535891839112183607157943692398769696531153719141528498448224128785868799210475) // + BigInt(3881175428498724209649715816699297677268154716152409333146177577349474565697791732)) + a98 = convert(T, + -BigInt(31140449219386755112730831706895080247696102690585728771850210691242594436100540310) // + BigInt(58531715707220748822628340615174217489020037018063169180406742622693159384762890406389)) + a101 = convert(T, + BigInt(24861126512935523838485032295435745281790804119672244200744512677831357181363) // + BigInt(215828469302253893975010055544246846578750854407392771457340001283636121600)) + a103 = convert(T, -76626859319946149305867456329803 // 167454524692981091214376557800) + a104 = convert(T, + BigInt(257532657386915224604779230484778835596042580268896440943054087972106955277512448850995064336363) // + BigInt(707777528357579864776572552477247532276956780876653359042572831013312547307465249178438602200)) + a105 = convert(T, + -BigInt(103092665221253777021612043042409780416654274677686197534469014507504059634284484983141143) // + BigInt(4735075386204034224907103653335170134874540866215348781137359896717512695961598377363000)) + a106 = convert(T, + BigInt(1318945254307068672853031172410281620677291556423152759282406612372948205789241763483098989903852936890735513699395545618802215742952753372919) // + BigInt(995520191927224509158660659519643916330847017611189618002256023928790665495276022949114110343406997764203331763292012060684160018593393766400)) + a107 = convert(T, + -BigInt(2175691361381933486174620849991740173349017185199505364607841) // + BigInt(482872625303278742130341621563226511344221688759361797916327450)) + a108 = convert(T, + -BigInt(11327601987184122343710458559595782081610122892585097) // + BigInt(21251874884678431935286330856983429378055579208005268000)) + b1 = convert(T, + BigInt(677260699094873524061210073954310211) // + BigInt(13212228177645157882237395248920447488)) + b4 = convert(T, + BigInt(5627843976805934592544586970647029617399366281651959837492864) // + BigInt(20448796992082885248862284273169726631726393791864145954479875)) + b5 = convert(T, + BigInt(1359735671458057021603668186882234273947181034928034734244224) // + BigInt(4035225037829041960922838374222759264846456609494840689395475)) + b6 = convert(T, + BigInt(3575764371063841994042920363615768888383369782579963896064642431626191680598750790399139608006651160426580137040859330533720256407) // + BigInt(18833618269956378326078572170759846509476617594300797062242096554507068838086062412372695473217373611870290738365243380652826304000)) + b7 = convert(T, + BigInt(14322850798205614664394883796805489119964080948503151) // + BigInt(1692788382425178679633337406927131793062126418747780)) + b8 = convert(T, + -BigInt(16735096417960349589058935251250023138290806176584545269411) // + BigInt(128573843052304513208482301684749747737236254208431871400)) + b9 = convert(T, + 33050288141543277444692395096256051 // 271248590133163812341791503489000) + # bhat1 =convert(T,BigInt(962650826879437817605721930727384851)//BigInt(18874611682350225546053421784172067840)) + # bhat4 =convert(T,BigInt(99703652969826806275610089806158069716600653757297413344)//BigInt(361062893830367886445877712954352019629670588714825566425)) + # bhat5 =convert(T,BigInt(17540887447270394964911517553576959050951784592644178144)//BigInt(52550888012671962193116521992300249584518949945887203425)) + # bhat6 =convert(T,BigInt(101855668513773837712956593596043266148479443244790887636953159551191054134940671472736229702711787350735239179)//BigInt(504322587935299170723833764883183242017770187561624249681119708768991642691172146267201689787026963930014131200)) + # bhat7 =convert(T,BigInt(179578338747395946570172802104016572846366090083599)//BigInt(31203472487100067827342625012481692038011546889360)) + # bhat8 =convert(T,-BigInt(500374162579884236288722085953024481890963958534161489781)//BigInt(5844265593286568782203740985670443078965284282201448700)) + # bhat10=convert(T,80) + btilde1 = convert(T, + BigInt(-11350400930890172457349074817136051) // + BigInt(44040760592150526274124650829734824960)) + btilde4 = convert(T, + BigInt(18872409140206580874590465524732661000311743892579167244576) // + BigInt(20448796992082885248862284273169726631726393791864145954479875)) + btilde5 = convert(T, + BigInt(-4274515681501734477669162831906773100582117137555409033632) // + BigInt(1345075012609680653640946124740919754948818869831613563131825)) + btilde6 = convert(T, + BigInt(151982138295746861476872192192436808638630079892291260212523545728864842939698890632387350810275352451114165347163409431707619557) // + BigInt(12555745513304252217385714780506564339651078396200531374828064369671379225390708274915130315478249074580193825576828920435217536000)) + btilde7 = convert(T, + BigInt(-6107634561545846083950679043550120057398294081957207) // + BigInt(2257051176566904906177783209236175724082835224997040)) + btilde8 = convert(T, + BigInt(1908954947067632130235683120094494845563199696277664164743) // + BigInt(42857947684101504402827433894916582579078751402810623800)) + btilde9 = convert(T, + -33050288141543277444692395096256051 // + 271248590133163812341791503489000) + btilde10 = convert(T, 80) + + TanYam7ConstantCache( + c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, + a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, + a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, + a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, + btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10) +end + +struct TsitPap8ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + c1::T2 + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + c8::T2 + c9::T2 + c10::T2 + a0201::T + a0301::T + a0302::T + a0401::T + a0403::T + a0501::T + a0503::T + a0504::T + a0601::T + a0604::T + a0605::T + a0701::T + a0704::T + a0705::T + a0706::T + a0801::T + a0804::T + a0805::T + a0806::T + a0807::T + a0901::T + a0904::T + a0905::T + a0906::T + a0907::T + a0908::T + a1001::T + a1004::T + a1005::T + a1006::T + a1007::T + a1008::T + a1009::T + a1101::T + a1104::T + a1105::T + a1106::T + a1107::T + a1108::T + a1109::T + a1110::T + a1201::T + a1204::T + a1205::T + a1206::T + a1207::T + a1208::T + a1209::T + a1210::T + a1211::T + a1301::T + a1304::T + a1305::T + a1306::T + a1307::T + a1308::T + a1309::T + a1310::T + b1::T + b6::T + b7::T + b8::T + b9::T + b10::T + b11::T + b12::T + btilde1::T + btilde6::T + btilde7::T + btilde8::T + btilde9::T + btilde10::T + btilde11::T + btilde12::T + btilde13::T +end + +""" +Cheap Error Estimation for Runge-Kutta methods, by Ch. Tsitouras and S.N. Papakostas, +Siam Journal on Scientific Computing, Vol. 20, Issue 6, Nov 1999. +""" +function TsitPap8ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + c1 = convert(T2, 0.06338028169014084) + c2 = convert(T2, 0.1027879458763643) + c3 = convert(T2, 0.15418191881454646) + c4 = convert(T2, 0.3875968992248062) + c5 = convert(T2, 0.4657534246575342) + c6 = convert(T2, 0.1554054054054054) + c7 = convert(T2, 1.0070921985815602) + c8 = convert(T2, 0.876141078561489) + c9 = convert(T2, 0.9120879120879121) + c10 = convert(T2, 0.959731543624161) + a0201 = convert(T, 0.06338028169014084) + a0301 = convert(T, 0.019438980427336498) + a0302 = convert(T, 0.08334896544902781) + a0401 = convert(T, 0.038545479703636615) + a0403 = convert(T, 0.11563643911090984) + a0501 = convert(T, 0.39436557770112496) + a0503 = convert(T, -1.4818719321673373) + a0504 = convert(T, 1.4751032536910185) + a0601 = convert(T, 0.045994489107698204) + a0604 = convert(T, 0.23235070626395474) + a0605 = convert(T, 0.18740822928588133) + a0701 = convert(T, 0.06005228953244051) + a0704 = convert(T, 0.11220383194636775) + a0705 = convert(T, -0.03357232951906142) + a0706 = convert(T, 0.016721613445658576) + a0801 = convert(T, -1.5733292732086857) + a0804 = convert(T, -1.3167087730223663) + a0805 = convert(T, -11.723515296181773) + a0806 = convert(T, 9.107825028173872) + a0807 = convert(T, 6.512820512820513) + a0901 = convert(T, -0.48107625624391254) + a0904 = convert(T, -6.6506103607463904) + a0905 = convert(T, -4.530206099782572) + a0906 = convert(T, 3.894414525020157) + a0907 = convert(T, 8.634217645525526) + a0908 = convert(T, 0.009401624788681498) + a1001 = convert(T, -0.7754121446230569) + a1004 = convert(T, -7.996604718235832) + a1005 = convert(T, -6.726558607230182) + a1006 = convert(T, 5.532184454327406) + a1007 = convert(T, 10.89757332024991) + a1008 = convert(T, 0.020091650280045396) + a1009 = convert(T, -0.039186042680376856) + a1101 = convert(T, -1.1896363245449992) + a1104 = convert(T, -7.128368483301214) + a1105 = convert(T, -9.53722789710108) + a1106 = convert(T, 7.574470108980868) + a1107 = convert(T, 11.267486382070919) + a1108 = convert(T, 0.051009801223058315) + a1109 = convert(T, 0.08019413469508256) + a1110 = convert(T, -0.15819617839847347) + a1201 = convert(T, -0.39200039047127266) + a1204 = convert(T, 3.916659042493856) + a1205 = convert(T, -2.8017459289080557) + a1206 = convert(T, 2.441204566481742) + a1207 = convert(T, -2.4183655778824718) + a1208 = convert(T, -0.33943326290032927) + a1209 = convert(T, 0.19496450383103364) + a1210 = convert(T, -0.19437176762508154) + a1211 = convert(T, 0.5930888149805791) + a1301 = convert(T, -1.4847063081291894) + a1304 = convert(T, -2.390723588981498) + a1305 = convert(T, -11.184306772840532) + a1306 = convert(T, 8.720804667459817) + a1307 = convert(T, 7.33673830753461) + a1308 = convert(T, 0.01289874999394761) + a1309 = convert(T, 0.042583289842657704) + a1310 = convert(T, -0.05328834487981156) + b1 = convert(T, 0.04441161093250152) + b6 = convert(T, 0.35395063113733116) + b7 = convert(T, 0.2485219684184965) + b8 = convert(T, -0.3326913171720666) + b9 = convert(T, 1.921248828652836) + b10 = convert(T, -2.7317783000882523) + b11 = convert(T, 1.4012004409899175) + b12 = convert(T, 0.0951361371292365) + # bhat1 =convert(T,0.044484201850329544) + # bhat6 =convert(T,0.35502352274458154) + # bhat7 =convert(T,0.24825530158391707) + # bhat8 =convert(T,-2.4242252962684616) + # bhat9 =convert(T,1.5999301534099692) + # bhat10=convert(T,-1.8107646286929684) + # bhat13=convert(T,2.9872967453726327) + btilde1 = convert(T, -7.259091782802626e-5) + btilde6 = convert(T, -0.0010728916072503584) + btilde7 = convert(T, 0.0002666668345794398) + btilde8 = convert(T, 2.091533979096395) + btilde9 = convert(T, 0.3213186752428666) + btilde10 = convert(T, -0.921013671395284) + btilde11 = convert(T, 1.4012004409899175) + btilde12 = convert(T, 0.0951361371292365) + btilde13 = convert(T, -2.9872967453726327) + + TsitPap8ConstantCache(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, + a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, + a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, + a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, + a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, + a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, + a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, + a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, + btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13) +end + +""" +Cheap Error Estimation for Runge-Kutta methods, by Ch. Tsitouras and S.N. Papakostas, +Siam Journal on Scientific Computing, Vol. 20, Issue 6, Nov 1999. +""" +function TsitPap8ConstantCache(T::Type, T2::Type) + c1 = convert(T2, 9 // 142) + c2 = convert(T2, 24514 // 238491) + c3 = convert(T2, 12257 // 79497) + c4 = convert(T2, 50 // 129) + c5 = convert(T2, 34 // 73) + c6 = convert(T2, 23 // 148) + c7 = convert(T2, 142 // 141) + c8 = convert(T2, 29104120198 // 33218531707) + c9 = convert(T2, 83 // 91) + c10 = convert(T2, 143 // 149) + a0201 = convert(T, 9 // 142) + a0301 = convert(T, 9950845450 // 511901613729) + a0302 = convert(T, 42666469916 // 511901613729) + a0401 = convert(T, 12257 // 317988) + a0403 = convert(T, 12257 // 105996) + a0501 = convert(T, 14131686489425 // 35833975601529) + a0503 = convert(T, -17700454220625 // 11944658533843) + a0504 = convert(T, 17619604667500 // 11944658533843) + a0601 = convert(T, 4418011 // 96055225) + a0604 = convert(T, 9757757988 // 41995818067) + a0605 = convert(T, 19921512441 // 106300094275) + a0701 = convert(T, 480285555889619 // 7997789253816320) + a0704 = convert(T, 52162106556696460538643 // 464887033284472899365888) + a0705 = convert(T, -16450769949384489 // 490009784398315520) + a0706 = convert(T, 864813381633887 // 51718297665732608) + a0801 = convert(T, -7001048352088587137143 // 4449830351030385148800) + a0804 = convert(T, -2522765548294599044197935933 // 1915963195493758447677901792) + a0805 = convert(T, -318556182235222634647116091 // 27172411532484037214054400) + a0806 = convert(T, 1205563885850790193966807 // 132365727505912221222912) + a0807 = convert(T, 254 // 39) + a0901 = convert(T, + -BigInt(20629396399716689122801179264428539394462855874226604463554767070845753369) // + BigInt(42881759662770155956657513470012114488076017981128105307375594963152353200)) + a0904 = convert(T, + -BigInt(3315443074343659404779422149387397712986453181141168247590906370819301077749322753) // + BigInt(498517112641608872807821838566847987729514312398278633788185835348997643218553476)) + a0905 = convert(T, + -BigInt(273749409411654060286948141164828452109898379203526945684314474186724062841643) // + BigInt(60427583951377552503967840653825589117167443021628367691773162913607984889600)) + a0906 = convert(T, + BigInt(16656372518874512738268060504309924900437672263609245028809229865738327731797537) // + BigInt(4276990138533930522782076385771016009097627930550149628282203007913538394549504)) + a0907 = convert(T, + BigInt(42008080033354305590804322944084805264441066760038302359736803632) // + BigInt(4865302423216534910074823287811605599629170295030631799935804001)) + a0908 = convert(T, + BigInt(668459780930716338000066627236927417191947396177093524377824) // + BigInt(71100452948884643779799087713322002499799983434685642170251833)) + a1001 = convert(T, + -BigInt(1793603946322260900828212460706877142477132870159527) // + BigInt(2313097568511990753781649719556084665131024900300800)) + a1004 = convert(T, + -BigInt(14776874123722838192315406145167687512425345723701) // + BigInt(1847893530366076701102014146927696206329050105856)) + a1005 = convert(T, + -BigInt(19587020919884661714856757105130246995757906603) // + BigInt(2911893296942532038566182868170393629789388800)) + a1006 = convert(T, + BigInt(6364380863259071677112259236455506477417699780613300364807) // + BigInt(1150428174584942133406579091549443438814988349188394057728)) + a1007 = convert(T, + BigInt(27725164402569748756040320433848245155581006369) // + BigInt(2544159473655547770881695354241256106302348256)) + a1008 = convert(T, + BigInt(10744247163960019876833255044784609639) // + BigInt(534761804739901348825491947768304503296)) + a1009 = convert(T, + -BigInt(50977737930792808232204417497248979399878217280011103197862899) // + BigInt(1300915694564913675613280314081837358644964393191337994183389184)) + a1101 = convert(T, + -BigInt(3587625717068952487214493441966897048737050755812600710793) // + BigInt(3015733164033229624772006086429467685046639983706974412800)) + a1104 = convert(T, + -BigInt(5453011711267804731211501837262816944661201619903) // + BigInt(764973320899716397072448644710733101329290196992)) + a1105 = convert(T, + -BigInt(884348836774584715070440485633026464653487653) // + BigInt(92725983515963799584249219499787659014963200)) + a1106 = convert(T, + BigInt(26823469063654084387375587616552322383082061411417182757389742951) // + BigInt(3541299744763681675473620647087123057228744296123642301654630400)) + a1107 = convert(T, + BigInt(142363419491686507162007051071007722765323162710521029) // + BigInt(12634887202368261565807449771335728082273587905775840)) + a1108 = convert(T, + BigInt(64747617454909275289531520412519442831235890581) // + BigInt(1269317188117975960996670628974453443777854830080)) + a1109 = convert(T, + BigInt(112633808253272720979874303367503891597499261046700689572459050065039333987335667) // + BigInt(1404514291245034532812181377119034501014039830518218465064579291611563374608650240)) + a1110 = convert(T, + -BigInt(10612202518573994431153697720606405883) // + BigInt(67082546658259846778754594976831647575)) + a1201 = convert(T, + -BigInt(7534081165544982478296202335922049210803875045423) // + BigInt(19219575665440848756074598051658416387002479820800)) + a1204 = convert(T, + BigInt(237696087452786717802270375283034262859273455) // + BigInt(60688480889936839261131818793519097177034752)) + a1205 = convert(T, + -BigInt(20610578209826329263318986584876108069323) // + BigInt(7356333776438834884293014575840932659200)) + a1206 = convert(T, + BigInt(51260471529841028040709654458903254781320136131844164563) // + BigInt(20998023776318546907382302106788168158765514131585630208)) + a1207 = convert(T, + -BigInt(3077214437173472971196810795615384000211457151011) // + BigInt(1272435592582280820597059432060116893200684680384)) + a1208 = convert(T, + -BigInt(1539218116260541896259682954580256454049) // + BigInt(4534670830750360983422999946409310393344)) + a1209 = convert(T, + BigInt(241886539350268429372116296787271276553970618941104594460614948326132797451456131) // + BigInt(1240669632662465892528916120041123051054026283188324780101555345343662316090597376)) + a1210 = convert(T, + -80556486832245966191717452425924975 // + 414445409518676597565032008051106461) + a1211 = convert(T, + BigInt(2944781680874500347594142792814463350) // + BigInt(4965161383073676983610218096030654529)) + a1301 = convert(T, + -BigInt(7757739937862944832927743694336116203639371542761) // + BigInt(5225100678421794325654850845451340473577260032000)) + a1304 = convert(T, + -BigInt(433889546009521405913741133329446636837810749) // + BigInt(181488796115643001621310691169322233346938880)) + a1305 = convert(T, + -BigInt(246044720162308748108107126829066792329071) // + BigInt(21999103311417807170100413255475150848000)) + a1306 = convert(T, + BigInt(2140331235425829844389060818616719848637810765257179167) // + BigInt(245428182036011897638028252815369258646052549878743040)) + a1307 = convert(T, + BigInt(1573990926219809229258666534611598771063240529) // + BigInt(214535514317495538101650508596881057760818080)) + a1308 = convert(T, + BigInt(62408280667309375445301959066100433563) // + BigInt(4838320046251983849512355559327451645440)) + a1309 = convert(T, + BigInt(1145609822249493677618113725359506642998153205603226883141207089968379) // + BigInt(26902802166822768476367427840835743139559294105398677975568538466119680)) + a1310 = convert(T, + -408950356875874683139089678053832 // + 7674292714443204070455739595109785) + b1 = convert(T, 55038446513529253801 // 1239280570055853383520) + b6 = convert(T, 2335496795323782464411846394611 // 6598368783294020109895379936256) + b7 = convert(T, 7636073376527143565375240869888 // 30725949199261296642046754748645) + b8 = convert(T, -4237087214169934312729607487 // 12735791394214625116604076160) + b9 = convert(T, + BigInt(408505291291133241760995514121984335914363927884426780078325258228227984174126699) // + BigInt(212624874612193697466655159405635202123821166475348052734199905546455860773575680)) + b10 = convert(T, -1108225296327029096435947 // 405679075893979729103310) + b11 = convert(T, 2460988291206213825688467985 // 1756342789520947764222671739) + b12 = convert(T, 4808707937311 // 50545545388065) + # bhat1 =convert(T,715953338020208413//16094552857868225760) + # bhat6 =convert(T,62284335162928966987066121//175437206755843240272669696) + # bhat7 =convert(T,184309146777472302831695872//742417767522160213324368465) + # bhat8 =convert(T,-509771598215811385123057257//210282269969085698264101760) + # bhat9 =convert(T,BigInt(2701602489646143640362891402924962500766379885231830470264478480621389)//BigInt(1688575269294196295712420798364925687791337062814161130291144634516480)) + # bhat10=convert(T,-7218534073012286740367561//3986456306153224954098780) + # bhat13=convert(T,5752173075461//1925544586212) + btilde1 = convert(T, -1124506425334925 // 15491007125698167294) + btilde6 = convert(T, -34035261967014004512968665 // 31722926842759712066804711232) + btilde7 = convert(T, 24580774837247048845194838016 // 92177847597783889926140264245935) + btilde8 = convert(T, 7658235379858959628545472335 // 3661540025836704721023671896) + btilde9 = convert(T, + BigInt(1510930663253486646384296195586886863633653147150681174690536256975353069486325) // + BigInt(4702280880846591386281796794547701585430660412435581935467882526508158459415616)) + btilde10 = convert(T, -237184116991804346989794715 // 257525077377498332034781188) + btilde11 = convert(T, 2460988291206213825688467985 // 1756342789520947764222671739) + btilde12 = convert(T, 4808707937311 // 50545545388065) + btilde13 = convert(T, -5752173075461 // 1925544586212) + + TsitPap8ConstantCache(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, + a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, + a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, + a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, + a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, + a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, + a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, + a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, + btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13) +end + +struct DP8ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + c7::T2 + c8::T2 + c9::T2 + c10::T2 + c11::T2 + c6::T2 + c5::T2 + c4::T2 + c3::T2 + c2::T2 + b1::T + b6::T + b7::T + b8::T + b9::T + b10::T + b11::T + b12::T + btilde1::T + btilde6::T + btilde7::T + btilde8::T + btilde9::T + btilde10::T + btilde11::T + btilde12::T + er1::T + er6::T + er7::T + er8::T + er9::T + er10::T + er11::T + er12::T + a0201::T + a0301::T + a0302::T + a0401::T + a0403::T + a0501::T + a0503::T + a0504::T + a0601::T + a0604::T + a0605::T + a0701::T + a0704::T + a0705::T + a0706::T + a0801::T + a0804::T + a0805::T + a0806::T + a0807::T + a0901::T + a0904::T + a0905::T + a0906::T + a0907::T + a0908::T + a1001::T + a1004::T + a1005::T + a1006::T + a1007::T + a1008::T + a1009::T + a1101::T + a1104::T + a1105::T + a1106::T + a1107::T + a1108::T + a1109::T + a1110::T + a1201::T + a1204::T + a1205::T + a1206::T + a1207::T + a1208::T + a1209::T + a1210::T + a1211::T + c14::T2 + c15::T2 + c16::T2 + a1401::T + a1407::T + a1408::T + a1409::T + a1410::T + a1411::T + a1412::T + a1413::T + a1501::T + a1506::T + a1507::T + a1508::T + a1511::T + a1512::T + a1513::T + a1514::T + a1601::T + a1606::T + a1607::T + a1608::T + a1609::T + a1613::T + a1614::T + a1615::T + d401::T + d406::T + d407::T + d408::T + d409::T + d410::T + d411::T + d412::T + d413::T + d414::T + d415::T + d416::T + d501::T + d506::T + d507::T + d508::T + d509::T + d510::T + d511::T + d512::T + d513::T + d514::T + d515::T + d516::T + d601::T + d606::T + d607::T + d608::T + d609::T + d610::T + d611::T + d612::T + d613::T + d614::T + d615::T + d616::T + d701::T + d706::T + d707::T + d708::T + d709::T + d710::T + d711::T + d712::T + d713::T + d714::T + d715::T + d716::T +end + +function DP8ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + c7 = convert(T2, 0.25) + c8 = convert(T2, 0.3076923076923077) + c9 = convert(T2, 0.6512820512820513) + c10 = convert(T2, 0.6) + c11 = convert(T2, 0.8571428571428571) + c6 = convert(T2, 0.3333333333333333) + c5 = convert(T2, 0.2816496580927726) + c4 = convert(T2, 0.1183503419072274) + c3 = convert(T2, 0.0789002279381516) + c2 = convert(T2, 0.05260015195876773) + b1 = convert(T, 0.054293734116568765) + b6 = convert(T, 4.450312892752409) + b7 = convert(T, 1.8915178993145003) + b8 = convert(T, -5.801203960010585) + b9 = convert(T, 0.3111643669578199) + b10 = convert(T, -0.1521609496625161) + b11 = convert(T, 0.20136540080403034) + b12 = convert(T, 0.04471061572777259) + # bhh1 = convert(T,0.2440944881889764) + # bhh2 = convert(T,0.7338466882816118) + # bhh3 = convert(T,0.022058823529411766) + btilde1 = convert(T, -0.18980075407240762) + btilde6 = convert(T, 4.450312892752409) + btilde7 = convert(T, 1.8915178993145003) + btilde8 = convert(T, -5.801203960010585) + btilde9 = convert(T, -0.42268232132379197) + btilde10 = convert(T, -0.1521609496625161) + btilde11 = convert(T, 0.20136540080403034) + btilde12 = convert(T, 0.022651792198360825) + er1 = convert(T, 0.01312004499419488) + er6 = convert(T, -1.2251564463762044) + er7 = convert(T, -0.4957589496572502) + er8 = convert(T, 1.6643771824549864) + er9 = convert(T, -0.35032884874997366) + er10 = convert(T, 0.3341791187130175) + er11 = convert(T, 0.08192320648511571) + er12 = convert(T, -0.022355307863886294) + a0201 = convert(T, 0.05260015195876773) + a0301 = convert(T, 0.0197250569845379) + a0302 = convert(T, 0.0591751709536137) + a0401 = convert(T, 0.02958758547680685) + a0403 = convert(T, 0.08876275643042054) + a0501 = convert(T, 0.2413651341592667) + a0503 = convert(T, -0.8845494793282861) + a0504 = convert(T, 0.924834003261792) + a0601 = convert(T, 0.037037037037037035) + a0604 = convert(T, 0.17082860872947386) + a0605 = convert(T, 0.12546768756682242) + a0701 = convert(T, 0.037109375) + a0704 = convert(T, 0.17025221101954405) + a0705 = convert(T, 0.06021653898045596) + a0706 = convert(T, -0.017578125) + a0801 = convert(T, 0.03709200011850479) + a0804 = convert(T, 0.17038392571223998) + a0805 = convert(T, 0.10726203044637328) + a0806 = convert(T, -0.015319437748624402) + a0807 = convert(T, 0.008273789163814023) + a0901 = convert(T, 0.6241109587160757) + a0904 = convert(T, -3.3608926294469414) + a0905 = convert(T, -0.868219346841726) + a0906 = convert(T, 27.59209969944671) + a0907 = convert(T, 20.154067550477894) + a0908 = convert(T, -43.48988418106996) + a1001 = convert(T, 0.47766253643826434) + a1004 = convert(T, -2.4881146199716677) + a1005 = convert(T, -0.590290826836843) + a1006 = convert(T, 21.230051448181193) + a1007 = convert(T, 15.279233632882423) + a1008 = convert(T, -33.28821096898486) + a1009 = convert(T, -0.020331201708508627) + a1101 = convert(T, -0.9371424300859873) + a1104 = convert(T, 5.186372428844064) + a1105 = convert(T, 1.0914373489967295) + a1106 = convert(T, -8.149787010746927) + a1107 = convert(T, -18.52006565999696) + a1108 = convert(T, 22.739487099350505) + a1109 = convert(T, 2.4936055526796523) + a1110 = convert(T, -3.0467644718982196) + a1201 = convert(T, 2.273310147516538) + a1204 = convert(T, -10.53449546673725) + a1205 = convert(T, -2.0008720582248625) + a1206 = convert(T, -17.9589318631188) + a1207 = convert(T, 27.94888452941996) + a1208 = convert(T, -2.8589982771350235) + a1209 = convert(T, -8.87285693353063) + a1210 = convert(T, 12.360567175794303) + a1211 = convert(T, 0.6433927460157636) + c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = DP8Interp( + T, + T2) + d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = DP8Interp_polyweights(T) + DP8ConstantCache( + c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, + b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, + btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, + a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, + a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, + a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, + a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, + a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, c14, c15, c16, + a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, + a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, + a1609, a1613, a1614, a1615, d401, d406, d407, d408, d409, d410, d411, + d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, + d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, + d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, + d712, d713, d714, d715, d716) +end + +function DP8ConstantCache(T::Type, T2::Type) + c7 = convert(T2, 1 // 4) + c8 = convert(T2, 4 // 13) + c9 = convert(T2, 127 // 195) + c10 = convert(T2, 3 // 5) + c11 = convert(T2, 6 // 7) + c6 = convert(T2, 4 // 3 * c7) + c5 = convert(T2, (6 + sqrt(6)) / 10 * c6) + c4 = convert(T2, (6 - sqrt(6)) / 10 * c6) + c3 = convert(T2, 2 // 3 * c4) + c2 = convert(T2, 2 // 3 * c3) + b1 = convert(T, big" 5.42937341165687622380535766363e-2") + b6 = convert(T, big" 4.45031289275240888144113950566") + b7 = convert(T, big" 1.89151789931450038304281599044") + b8 = convert(T, big"-5.8012039600105847814672114227") + b9 = convert(T, big" 3.1116436695781989440891606237e-1") + b10 = convert(T, big"-1.52160949662516078556178806805e-1") + b11 = convert(T, big" 2.01365400804030348374776537501e-1") + b12 = convert(T, big" 4.47106157277725905176885569043e-2") + # bhh1 = convert(T,big"0.244094488188976377952755905512") + # bhh2 = convert(T,big"0.733846688281611857341361741547") + # bhh3 = convert(T,big"0.220588235294117647058823529412e-01") + btilde1 = convert(T, big"-1.898007540724076157147023288757e-1") + btilde6 = convert(T, big" 4.45031289275240888144113950566") + btilde7 = convert(T, big" 1.89151789931450038304281599044") + btilde8 = convert(T, big"-5.8012039600105847814672114227") + btilde9 = convert(T, big"-4.22682321323791962932445679177e-1") + btilde10 = convert(T, big"-1.52160949662516078556178806805e-1") + btilde11 = convert(T, big" 2.01365400804030348374776537501e-1") + btilde12 = convert(T, big"2.26517921983608258118062039631e-2") + er1 = convert(T, big" 0.1312004499419488073250102996e-01") + er6 = convert(T, big"-0.1225156446376204440720569753e+01") + er7 = convert(T, big"-0.4957589496572501915214079952") + er8 = convert(T, big" 0.1664377182454986536961530415e+01") + er9 = convert(T, big"-0.3503288487499736816886487290") + er10 = convert(T, big" 0.3341791187130174790297318841") + er11 = convert(T, big" 0.8192320648511571246570742613e-01") + er12 = convert(T, big"-0.2235530786388629525884427845e-01") + a0201 = convert(T, big" 5.26001519587677318785587544488e-2") + a0301 = convert(T, big" 1.97250569845378994544595329183e-2") + a0302 = convert(T, big" 5.91751709536136983633785987549e-2") + a0401 = convert(T, big" 2.95875854768068491816892993775e-2") + a0403 = convert(T, big" 8.87627564304205475450678981324e-2") + a0501 = convert(T, big" 2.41365134159266685502369798665e-1") + a0503 = convert(T, big"-8.84549479328286085344864962717e-1") + a0504 = convert(T, big" 9.24834003261792003115737966543e-1") + a0601 = convert(T, big" 3.7037037037037037037037037037e-2") + a0604 = convert(T, big" 1.70828608729473871279604482173e-1") + a0605 = convert(T, big" 1.25467687566822425016691814123e-1") + a0701 = convert(T, big" 3.7109375e-2") + a0704 = convert(T, big" 1.70252211019544039314978060272e-1") + a0705 = convert(T, big" 6.02165389804559606850219397283e-2") + a0706 = convert(T, big"-1.7578125e-2") + a0801 = convert(T, big" 3.70920001185047927108779319836e-2") + a0804 = convert(T, big" 1.70383925712239993810214054705e-1") + a0805 = convert(T, big" 1.07262030446373284651809199168e-1") + a0806 = convert(T, big"-1.53194377486244017527936158236e-2") + a0807 = convert(T, big" 8.27378916381402288758473766002e-3") + a0901 = convert(T, big" 6.24110958716075717114429577812e-1") + a0904 = convert(T, big"-3.36089262944694129406857109825") + a0905 = convert(T, big"-8.68219346841726006818189891453e-1") + a0906 = convert(T, big" 2.75920996994467083049415600797e1") + a0907 = convert(T, big" 2.01540675504778934086186788979e1") + a0908 = convert(T, big"-4.34898841810699588477366255144e1") + a1001 = convert(T, big" 4.77662536438264365890433908527e-1") + a1004 = convert(T, big"-2.48811461997166764192642586468e0") + a1005 = convert(T, big"-5.90290826836842996371446475743e-1") + a1006 = convert(T, big" 2.12300514481811942347288949897e1") + a1007 = convert(T, big" 1.52792336328824235832596922938e1") + a1008 = convert(T, big"-3.32882109689848629194453265587e1") + a1009 = convert(T, big"-2.03312017085086261358222928593e-2") + a1101 = convert(T, big"-9.3714243008598732571704021658e-1") + a1104 = convert(T, big" 5.18637242884406370830023853209e0") + a1105 = convert(T, big" 1.09143734899672957818500254654e0") + a1106 = convert(T, big"-8.14978701074692612513997267357e0") + a1107 = convert(T, big"-1.85200656599969598641566180701e1") + a1108 = convert(T, big" 2.27394870993505042818970056734e1") + a1109 = convert(T, big" 2.49360555267965238987089396762e0") + a1110 = convert(T, big"-3.0467644718982195003823669022e0") + a1201 = convert(T, big" 2.27331014751653820792359768449e0") + a1204 = convert(T, big" -1.05344954667372501984066689879e1") + a1205 = convert(T, big" -2.00087205822486249909675718444e0") + a1206 = convert(T, big" -1.79589318631187989172765950534e1") + a1207 = convert(T, big" 2.79488845294199600508499808837e1") + a1208 = convert(T, big" -2.85899827713502369474065508674e0") + a1209 = convert(T, big" -8.87285693353062954433549289258e0") + a1210 = convert(T, big" 1.23605671757943030647266201528e1") + a1211 = convert(T, big" 6.43392746015763530355970484046e-1") + c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = DP8Interp( + T, + T2) + d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = DP8Interp_polyweights(T) + DP8ConstantCache( + c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, + b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, + btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, + a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, + a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, + a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, + a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, + a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, c14, c15, c16, + a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, + a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, + a1609, a1613, a1614, a1615, d401, d406, d407, d408, d409, d410, d411, + d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, + d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, + d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, + d712, d713, d714, d715, d716) +end + +function DP8Interp(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + c14 = convert(T2, 0.1) + c15 = convert(T2, 0.2) + c16 = convert(T2, 0.7777777777777778) + a1401 = convert(T, 0.056167502283047954) + a1407 = convert(T, 0.25350021021662483) + a1408 = convert(T, -0.2462390374708025) + a1409 = convert(T, -0.12419142326381637) + a1410 = convert(T, 0.15329179827876568) + a1411 = convert(T, 0.00820105229563469) + a1412 = convert(T, 0.007567897660545699) + a1413 = convert(T, -0.008298) + a1501 = convert(T, 0.03183464816350214) + a1506 = convert(T, 0.028300909672366776) + a1507 = convert(T, 0.053541988307438566) + a1508 = convert(T, -0.05492374857139099) + a1511 = convert(T, -0.00010834732869724932) + a1512 = convert(T, 0.0003825710908356584) + a1513 = convert(T, -0.00034046500868740456) + a1514 = convert(T, 0.1413124436746325) + a1601 = convert(T, -0.42889630158379194) + a1606 = convert(T, -4.697621415361164) + a1607 = convert(T, 7.683421196062599) + a1608 = convert(T, 4.06898981839711) + a1609 = convert(T, 0.3567271874552811) + a1613 = convert(T, -0.0013990241651590145) + a1614 = convert(T, 2.9475147891527724) + a1615 = convert(T, -9.15095847217987) + + return c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, + a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, + a1609, a1613, a1614, a1615 +end + +function DP8Interp(T::Type, T2::Type) + c14 = convert(T2, 1 // 10) + c15 = convert(T2, 2 // 10) + c16 = convert(T2, 7 // 9) + a1401 = convert(T, big" 5.61675022830479523392909219681e-2") + a1407 = convert(T, big" 2.53500210216624811088794765333e-1") + a1408 = convert(T, big"-2.46239037470802489917441475441e-1") + a1409 = convert(T, big"-1.24191423263816360469010140626e-1") + a1410 = convert(T, big" 1.5329179827876569731206322685e-1") + a1411 = convert(T, big" 8.20105229563468988491666602057e-3") + a1412 = convert(T, big" 7.56789766054569976138603589584e-3") + a1413 = convert(T, big"-8.298e-3") + a1501 = convert(T, big" 3.18346481635021405060768473261e-2") + a1506 = convert(T, big" 2.83009096723667755288322961402e-2") + a1507 = convert(T, big" 5.35419883074385676223797384372e-2") + a1508 = convert(T, big"-5.49237485713909884646569340306e-2") + a1511 = convert(T, big"-1.08347328697249322858509316994e-4") + a1512 = convert(T, big" 3.82571090835658412954920192323e-4") + a1513 = convert(T, big"-3.40465008687404560802977114492e-4") + a1514 = convert(T, big" 1.41312443674632500278074618366e-1") + a1601 = convert(T, big"-4.28896301583791923408573538692e-1") + a1606 = convert(T, big"-4.69762141536116384314449447206e0") + a1607 = convert(T, big" 7.68342119606259904184240953878e0") + a1608 = convert(T, big" 4.06898981839711007970213554331e0") + a1609 = convert(T, big" 3.56727187455281109270669543021e-1") + a1613 = convert(T, big"-1.39902416515901462129418009734e-3") + a1614 = convert(T, big" 2.9475147891527723389556272149e0") + a1615 = convert(T, big"-9.15095847217987001081870187138e0") + + return c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, + a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, + a1609, a1613, a1614, a1615 +end + +function DP8Interp_polyweights(T::Type{<:CompiledFloats}) + d401 = convert(T, -8.428938276109013) + d406 = convert(T, 0.5667149535193777) + d407 = convert(T, -3.0689499459498917) + d408 = convert(T, 2.38466765651207) + d409 = convert(T, 2.117034582445028) + d410 = convert(T, -0.871391583777973) + d411 = convert(T, 2.2404374302607883) + d412 = convert(T, 0.6315787787694688) + d413 = convert(T, -0.08899033645133331) + d414 = convert(T, 18.148505520854727) + d415 = convert(T, -9.194632392478356) + d416 = convert(T, -4.436036387594894) + d501 = convert(T, 10.427508642579134) + d506 = convert(T, 242.28349177525817) + d507 = convert(T, 165.20045171727028) + d508 = convert(T, -374.5467547226902) + d509 = convert(T, -22.113666853125306) + d510 = convert(T, 7.733432668472264) + d511 = convert(T, -30.674084731089398) + d512 = convert(T, -9.332130526430229) + d513 = convert(T, 15.697238121770845) + d514 = convert(T, -31.139403219565178) + d515 = convert(T, -9.35292435884448) + d516 = convert(T, 35.81684148639408) + d601 = convert(T, 19.985053242002433) + d606 = convert(T, -387.0373087493518) + d607 = convert(T, -189.17813819516758) + d608 = convert(T, 527.8081592054236) + d609 = convert(T, -11.57390253995963) + d610 = convert(T, 6.8812326946963) + d611 = convert(T, -1.0006050966910838) + d612 = convert(T, 0.7777137798053443) + d613 = convert(T, -2.778205752353508) + d614 = convert(T, -60.19669523126412) + d615 = convert(T, 84.32040550667716) + d616 = convert(T, 11.99229113618279) + d701 = convert(T, -25.69393346270375) + d706 = convert(T, -154.18974869023643) + d707 = convert(T, -231.5293791760455) + d708 = convert(T, 357.6391179106141) + d709 = convert(T, 93.40532418362432) + d710 = convert(T, -37.45832313645163) + d711 = convert(T, 104.0996495089623) + d712 = convert(T, 29.8402934266605) + d713 = convert(T, -43.53345659001114) + d714 = convert(T, 96.32455395918828) + d715 = convert(T, -39.17726167561544) + d716 = convert(T, -149.72683625798564) + + return d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, + d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, + d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, + d708, d709, d710, d711, d712, d713, d714, d715, d716 +end + +function DP8Interp_polyweights(T::Type) + d401 = convert(T, big"-0.84289382761090128651353491142e+01") + d406 = convert(T, big" 0.56671495351937776962531783590e+00") + d407 = convert(T, big"-0.30689499459498916912797304727e+01") + d408 = convert(T, big" 0.23846676565120698287728149680e+01") + d409 = convert(T, big" 0.21170345824450282767155149946e+01") + d410 = convert(T, big"-0.87139158377797299206789907490e+00") + d411 = convert(T, big" 0.22404374302607882758541771650e+01") + d412 = convert(T, big" 0.63157877876946881815570249290e+00") + d413 = convert(T, big"-0.88990336451333310820698117400e-01") + d414 = convert(T, big" 0.18148505520854727256656404962e+02") + d415 = convert(T, big"-0.91946323924783554000451984436e+01") + d416 = convert(T, big"-0.44360363875948939664310572000e+01") + d501 = convert(T, big" 0.10427508642579134603413151009e+02") + d506 = convert(T, big" 0.24228349177525818288430175319e+03") + d507 = convert(T, big" 0.16520045171727028198505394887e+03") + d508 = convert(T, big"-0.37454675472269020279518312152e+03") + d509 = convert(T, big"-0.22113666853125306036270938578e+02") + d510 = convert(T, big" 0.77334326684722638389603898808e+01") + d511 = convert(T, big"-0.30674084731089398182061213626e+02") + d512 = convert(T, big"-0.93321305264302278729567221706e+01") + d513 = convert(T, big" 0.15697238121770843886131091075e+02") + d514 = convert(T, big"-0.31139403219565177677282850411e+02") + d515 = convert(T, big"-0.93529243588444783865713862664e+01") + d516 = convert(T, big" 0.35816841486394083752465898540e+02") + d601 = convert(T, big" 0.19985053242002433820987653617e+02") + d606 = convert(T, big"-0.38703730874935176555105901742e+03") + d607 = convert(T, big"-0.18917813819516756882830838328e+03") + d608 = convert(T, big" 0.52780815920542364900561016686e+03") + d609 = convert(T, big"-0.11573902539959630126141871134e+02") + d610 = convert(T, big" 0.68812326946963000169666922661e+01") + d611 = convert(T, big"-0.10006050966910838403183860980e+01") + d612 = convert(T, big" 0.77771377980534432092869265740e+00") + d613 = convert(T, big"-0.27782057523535084065932004339e+01") + d614 = convert(T, big"-0.60196695231264120758267380846e+02") + d615 = convert(T, big" 0.84320405506677161018159903784e+02") + d616 = convert(T, big" 0.11992291136182789328035130030e+02") + d701 = convert(T, big"-0.25693933462703749003312586129e+02") + d706 = convert(T, big"-0.15418974869023643374053993627e+03") + d707 = convert(T, big"-0.23152937917604549567536039109e+03") + d708 = convert(T, big" 0.35763911791061412378285349910e+03") + d709 = convert(T, big" 0.93405324183624310003907691704e+02") + d710 = convert(T, big"-0.37458323136451633156875139351e+02") + d711 = convert(T, big" 0.10409964950896230045147246184e+03") + d712 = convert(T, big" 0.29840293426660503123344363579e+02") + d713 = convert(T, big"-0.43533456590011143754432175058e+02") + d714 = convert(T, big" 0.96324553959188282948394950600e+02") + d715 = convert(T, big"-0.39177261675615439165231486172e+02") + d716 = convert(T, big"-0.14972683625798562581422125276e+03") + + return d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, + d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, + d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, + d708, d709, d710, d711, d712, d713, d714, d715, d716 +end +struct PFRK87ConstantCache{T1, T2} <: OrdinaryDiffEqConstantCache + α0201::T1 + α0301::T1 + α0401::T1 + α0501::T1 + α0601::T1 + α0701::T1 + + α0302::T1 + + α0403::T1 + α0503::T1 + + α0504::T1 + α0604::T1 + α0704::T1 + + α0605::T1 + α0705::T1 + + α0706::T1 + + α0908::T1 + α1008::T1 + α1108::T1 + α1208::T1 + α1308::T1 + + α1009::T1 + α1109::T1 + α1209::T1 + α1309::T1 + + α1110::T1 + α1210::T1 + α1310::T1 + + α1211::T1 + α1311::T1 + + β1::T1 + β6::T1 + β7::T1 + β8::T1 + β9::T1 + β10::T1 + β11::T1 + β12::T1 + β13::T1 + + β1tilde::T1 + β6tilde::T1 + β7tilde::T1 + β8tilde::T1 + β9tilde::T1 + β10tilde::T1 + β11tilde::T1 + β12tilde::T1 + + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + c8::T2 + c9::T2 + c10::T2 + c11::T2 + c12::T2 + c13::T2 +end + +function PFRK87ConstantCache(T1::Type, T2::Type) + + # elements of Butcher Table + α0201 = convert(T1, 1 // 18) + α0301 = convert(T1, 1 // 48) + α0401 = convert(T1, 1 // 32) + α0501 = convert(T1, 5 // 16) + α0601 = convert(T1, 3 // 80) + α0701 = convert(T1, 29443841 // 614563906) + + α0302 = convert(T1, 1 // 16) + + α0403 = convert(T1, 3 // 32) + α0503 = convert(T1, -75 // 64) + + α0504 = convert(T1, 75 // 64) + α0604 = convert(T1, 3 // 16) + α0704 = convert(T1, 77736538 // 692538347) + + α0605 = convert(T1, 3 // 20) + α0705 = convert(T1, -28693883 // 1125000000) + + α0706 = convert(T1, 23124283 // 1800000000) + + α0908 = convert(T1, 800635310 // 3783071287) + α1008 = convert(T1, 393006217 // 1396673457) + α1108 = convert(T1, 15336726248 // 1032824649) + α1208 = convert(T1, 5232866602 // 850066563) + α1308 = convert(T1, -13158990841 // 6184727034) + + α1009 = convert(T1, 123872331 // 1001029789) + α1109 = convert(T1, -45442868181 // 3398467696) + α1209 = convert(T1, -4093664535 // 808688257) + α1309 = convert(T1, 3936647629 // 1978049680) + + α1110 = convert(T1, 3065993473 // 597172653) + α1210 = convert(T1, 3962137247 // 1805957418) + α1310 = convert(T1, -160528059 // 685178525) + + α1211 = convert(T1, 65686358 // 487910083) + α1311 = convert(T1, 248638103 // 1413531060) + + β1 = convert(T1, 14005451 // 335480064) + β6 = convert(T1, -59238493 // 1068277825) + β7 = convert(T1, 181606767 // 758867731) + β8 = convert(T1, 561292985 // 797845732) + β9 = convert(T1, -1041891430 // 1371343529) + β10 = convert(T1, 760417239 // 1151165299) + β11 = convert(T1, 118820643 // 751138087) + β12 = convert(T1, -528747749 // 2220607170) + β13 = convert(T1, 1 // 4) + + β1tilde = convert(T1, 13451932 // 455176623) + β6tilde = convert(T1, -808719846 // 976000145) + β7tilde = convert(T1, 1757004468 // 5645159321) + β8tilde = convert(T1, 656045339 // 265891186) + β9tilde = convert(T1, -3867574721 // 1518517206) + β10tilde = convert(T1, 465885868 // 322736535) + β11tilde = convert(T1, 53011238 // 667516719) + β12tilde = convert(T1, 2 // 45) + + c2 = convert(T2, 1 // 18) + c3 = convert(T2, 1 // 12) + c4 = convert(T2, 1 // 8) + c5 = convert(T2, 5 // 16) + c6 = convert(T2, 3 // 8) + c7 = convert(T2, 59 // 400) + c8 = convert(T2, 93 // 200) + c9 = convert(T2, 5490023248 // 9719169821) + c10 = convert(T2, 13 // 20) + c11 = convert(T2, 1201146811 // 1299019798) + c12 = convert(T2, 1 // 1) + c13 = convert(T2, 1 // 1) + + PFRK87ConstantCache(α0201, α0301, α0401, α0501, α0601, α0701, α0302, α0403, α0503, + α0504, α0604, α0704, α0605, α0705, α0706, α0908, α1008, α1108, + α1208, α1308, α1009, α1109, α1209, α1309, α1110, α1210, α1310, + α1211, α1311, β1, β6, β7, β8, β9, β10, β11, β12, β13, β1tilde, + β6tilde, β7tilde, β8tilde, β9tilde, β10tilde, β11tilde, β12tilde, + c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) +end diff --git a/src/tableaus/low_order_rk_tableaus.jl b/src/tableaus/low_order_rk_tableaus.jl new file mode 100644 index 0000000000..0dde8ad263 --- /dev/null +++ b/src/tableaus/low_order_rk_tableaus.jl @@ -0,0 +1,2186 @@ +struct BS3ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + a32::T + a41::T + a42::T + a43::T + c1::T2 + c2::T2 + btilde1::T + btilde2::T + btilde3::T + btilde4::T +end + +""" +constructBogakiShampine3() + +Constructs the tableau object for the Bogakai-Shampine Order 2/3 method. +""" +function BS3ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + a21 = convert(T, 0.5) + a32 = convert(T, 0.75) + a41 = convert(T, 0.2222222222222222) + a42 = convert(T, 0.3333333333333333) + a43 = convert(T, 0.4444444444444444) + c1 = convert(T2, 0.5) + c2 = convert(T2, 0.75) + # b1 = convert(T,0.2916666666666667) + # b2 = convert(T,0.25) + # b3 = convert(T,0.3333333333333333) + # b4 = convert(T,0.125) + btilde1 = convert(T, 0.06944444444444445) + btilde2 = convert(T, -0.08333333333333333) + btilde3 = convert(T, -0.1111111111111111) + btilde4 = convert(T, 0.125) + BS3ConstantCache(a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4) +end + +""" +constructBogakiShampine3() + +Constructs the tableau object for the Bogakai-Shampine Order 2/3 method. +""" +function BS3ConstantCache(T::Type, T2::Type) + a21 = convert(T, 1 // 2) + a32 = convert(T, 3 // 4) + a41 = convert(T, 2 // 9) + a42 = convert(T, 1 // 3) + a43 = convert(T, 4 // 9) + c1 = convert(T2, 1 // 2) + c2 = convert(T2, 3 // 4) + # b1 = convert(T,7//24) + # b2 = convert(T,1//4) + # b3 = convert(T,1//3) + # b4 = convert(T,1//8) + btilde1 = convert(T, 5 // 72) + btilde2 = convert(T, -1 // 12) + btilde3 = convert(T, -1 // 9) + btilde4 = convert(T, 1 // 8) + BS3ConstantCache(a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4) +end + +struct OwrenZen3ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + c1::T2 + c2::T2 + btilde1::T + btilde2::T + btilde3::T + r13::T + r12::T + r23::T + r22::T + r33::T + r32::T +end + +function OwrenZen3ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + a21 = convert(T, 0.5217391304347826) + a31 = convert(T, -0.18133333333333335) + a32 = convert(T, 0.9813333333333333) + a41 = convert(T, 0.2152777777777778) + a42 = convert(T, 0.4592013888888889) + a43 = convert(T, 0.3255208333333333) + c1 = convert(T2, 0.5217391304347826) + c2 = convert(T2, 0.8) + # b1 = convert(T,0.041666666666666664) + # b2 = convert(T,0.9583333333333334) + btilde1 = convert(T, -0.1736111111111111) + btilde2 = convert(T, 0.4991319444444444) + btilde3 = convert(T, -0.3255208333333333) + r13 = convert(T, 0.5694444444444444) + r12 = convert(T, -1.3541666666666667) + r23 = convert(T, -0.9184027777777778) + r22 = convert(T, 1.3776041666666667) + r33 = convert(T, -0.6510416666666666) + r32 = convert(T, 0.9765625) + OwrenZen3ConstantCache(a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, + r13, r12, r23, r22, r33, r32) +end + +function OwrenZen3ConstantCache(T, T2) + a21 = convert(T, 12 // 23) + a31 = convert(T, -68 // 375) + a32 = convert(T, 368 // 375) + a41 = convert(T, 31 // 144) + a42 = convert(T, 529 // 1152) + a43 = convert(T, 125 // 384) + c1 = convert(T2, 12 // 23) + c2 = convert(T2, 4 // 5) + # b1 = convert(T,1//24) + # b2 = convert(T,23//24) + btilde1 = convert(T, -25 // 144) + btilde2 = convert(T, 575 // 1152) + btilde3 = convert(T, -125 // 384) + r13 = convert(T, 41 // 72) + r12 = convert(T, -65 // 48) + r23 = convert(T, -529 // 576) + r22 = convert(T, 529 // 384) + r33 = convert(T, -125 // 192) + r32 = convert(T, 125 // 128) + OwrenZen3ConstantCache(a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, + r13, r12, r23, r22, r33, r32) +end + +struct OwrenZen4ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a63::T + a64::T + a65::T + c1::T2 + c2::T2 + c3::T2 + c4::T2 + btilde1::T + btilde3::T + btilde4::T + btilde5::T + r14::T + r13::T + r12::T + r34::T + r33::T + r32::T + r44::T + r43::T + r42::T + r54::T + r53::T + r52::T + r64::T + r63::T + r62::T +end + +function OwrenZen4ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + a21 = convert(T, 0.16666666666666666) + a31 = convert(T, 0.03214024835646457) + a32 = convert(T, 0.26515704894083275) + a41 = convert(T, 0.6895990230002036) + a42 = convert(T, -1.6993690209647874) + a43 = convert(T, 1.6568288214939955) + a51 = convert(T, -0.09002509947964493) + a52 = convert(T, 0.6817777777777778) + a53 = convert(T, -0.2402791551882461) + a54 = convert(T, 0.5151931435567799) + a61 = convert(T, 0.08990252172070354) + a63 = convert(T, 0.4360623278236915) + a64 = convert(T, 0.1842858372687918) + a65 = convert(T, 0.2897493131868132) + c1 = convert(T2, 0.16666666666666666) + c2 = convert(T2, 0.2972972972972973) + c3 = convert(T2, 0.6470588235294118) + c4 = convert(T2, 0.8666666666666667) + # b1 = convert(T,0.27823691460055094) + # b3 = convert(T,-0.09428374655647383) + # b4 = convert(T,0.8160468319559229) + btilde1 = convert(T, 0.18833439287984743) + btilde3 = convert(T, -0.5303460743801653) + btilde4 = convert(T, 0.6317609946871311) + btilde5 = convert(T, -0.2897493131868132) + r14 = convert(T, -1.0513495872621479) + r13 = convert(T, 2.922894131082889) + r12 = convert(T, -2.7816420221000375) + r34 = convert(T, 2.4266369235379472) + r33 = convert(T, -5.725398502723277) + r32 = convert(T, 3.7348239070090217) + r44 = convert(T, -0.7705135914137909) + r43 = convert(T, 1.1724555082899983) + r42 = convert(T, -0.21765607960741548) + r54 = convert(T, -2.8643157295948325) + r53 = convert(T, 5.149132832816039) + r52 = convert(T, -1.9950677900343932) + r64 = convert(T, 2.2595419847328246) + r63 = convert(T, -3.519083969465649) + r62 = convert(T, 1.2595419847328244) + OwrenZen4ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, + btilde5, + r14, r13, r12, r34, r33, r32, r44, r43, r42, + r54, r53, r52, r64, r63, r62) +end + +function OwrenZen4ConstantCache(T, T2) + a21 = convert(T, 1 // 6) + a31 = convert(T, 44 // 1369) + a32 = convert(T, 363 // 1369) + a41 = convert(T, 3388 // 4913) + a42 = convert(T, -8349 // 4913) + a43 = convert(T, 8140 // 4913) + a51 = convert(T, -36764 // 408375) + a52 = convert(T, 767 // 1125) + a53 = convert(T, -32708 // 136125) + a54 = convert(T, 210392 // 408375) + a61 = convert(T, 1697 // 18876) + a63 = convert(T, 50653 // 116160) + a64 = convert(T, 299693 // 1626240) + a65 = convert(T, 3375 // 11648) + c1 = convert(T2, 1 // 6) + c2 = convert(T2, 11 // 37) + c3 = convert(T2, 11 // 17) + c4 = convert(T2, 13 // 15) + # b1 = convert(T,101//363) + # b3 = convert(T,-1369//14520) + # b4 = convert(T,11849//14520) + btilde1 = convert(T, 1185 // 6292) + btilde3 = convert(T, -4107 // 7744) + btilde4 = convert(T, 68493 // 108416) + btilde5 = convert(T, -3375 // 11648) + r14 = convert(T, -866577 // 824252) + r13 = convert(T, 1806901 // 618189) + r12 = convert(T, -104217 // 37466) + r34 = convert(T, 12308679 // 5072320) + r33 = convert(T, -2178079 // 380424) + r32 = convert(T, 861101 // 230560) + r44 = convert(T, -7816583 // 10144640) + r43 = convert(T, 6244423 // 5325936) + r42 = convert(T, -63869 // 293440) + r54 = convert(T, -624375 // 217984) + r53 = convert(T, 982125 // 190736) + r52 = convert(T, -1522125 // 762944) + r64 = convert(T, 296 // 131) + r63 = convert(T, -461 // 131) + r62 = convert(T, 165 // 131) + OwrenZen4ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, + btilde5, + r14, r13, r12, r34, r33, r32, r44, r43, r42, + r54, r53, r52, r64, r63, r62) +end + +struct OwrenZen5ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + a81::T + a83::T + a84::T + a85::T + a86::T + a87::T + c1::T2 + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + btilde1::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + r15::T + r14::T + r13::T + r12::T + r35::T + r34::T + r33::T + r32::T + r45::T + r44::T + r43::T + r42::T + r55::T + r54::T + r53::T + r52::T + r65::T + r64::T + r63::T + r62::T + r75::T + r74::T + r73::T + r72::T + r85::T + r84::T + r83::T + r82::T +end + +function OwrenZen5ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + a21 = convert(T, 0.16666666666666666) + a31 = convert(T, 0.0625) + a32 = convert(T, 0.1875) + a41 = convert(T, 0.25) + a42 = convert(T, -0.75) + a51 = convert(T, -0.75) + a52 = convert(T, 3.75) + a53 = convert(T, -3.0) + a54 = convert(T, 0.5) + a61 = convert(T, 0.26895043731778423) + a62 = convert(T, -0.7084548104956269) + a63 = convert(T, 0.8658892128279884) + a64 = convert(T, 0.15462307371928363) + a65 = convert(T, 0.06184922948771345) + a71 = convert(T, -0.02947695035460993) + a72 = convert(T, 0.18500664893617022) + a73 = convert(T, 0.4802345261121857) + a74 = convert(T, -0.5337849069148937) + a75 = convert(T, -0.013090093085106383) + a76 = convert(T, 0.7861107753062541) + a81 = convert(T, 0.08783068783068783) + a83 = convert(T, 0.3006060606060606) + a84 = convert(T, 0.22777777777777777) + a85 = convert(T, 0.027777777777777776) + a86 = convert(T, 0.06218596218596219) + a87 = convert(T, 0.2938217338217338) + c1 = convert(T2, 0.16666666666666666) + c2 = convert(T2, 0.25) + c3 = convert(T2, 0.5) + c4 = convert(T2, 0.5) + c5 = convert(T2, 0.6428571428571429) + c6 = convert(T2, 0.875) + # b1 = convert(T,-0.1111111111111111) + # b3 = convert(T,1.2121212121212122) + # b4 = convert(T,-1.75) + # b5 = convert(T,-0.08333333333333333) + # b6 = convert(T,1.7323232323232323) + btilde1 = convert(T, -0.19894179894179895) + btilde3 = convert(T, 0.9115151515151515) + btilde4 = convert(T, -1.9777777777777779) + btilde5 = convert(T, -0.1111111111111111) + btilde6 = convert(T, 1.67013727013727) + btilde7 = convert(T, -0.2938217338217338) + r15 = convert(T, 1.892063492063492) + r14 = convert(T, -6.067155067155067) + r13 = convert(T, 7.282458282458283) + r12 = convert(T, -4.0195360195360195) + r35 = convert(T, -7.214545454545455) + r34 = convert(T, 20.676923076923078) + r33 = convert(T, -20.31142191142191) + r32 = convert(T, 7.14965034965035) + r45 = convert(T, 7.866666666666666) + r44 = convert(T, -18.78205128205128) + r43 = convert(T, 13.508547008547009) + r42 = convert(T, -2.3653846153846154) + r55 = convert(T, 2) + r54 = convert(T, -5.294871794871795) + r53 = convert(T, 4.534188034188034) + r52 = convert(T, -1.2115384615384615) + r65 = convert(T, -1.4924630924630924) + r64 = convert(T, 1.5785667324128863) + r63 = convert(T, 1.1958838881915805) + r62 = convert(T, -1.219801565955412) + r75 = convert(T, -7.051721611721612) + r74 = convert(T, 16.273203719357564) + r73 = convert(T, -11.978886071193763) + r72 = convert(T, 3.0512256973795435) + r85 = convert(T, 4) + r84 = convert(T, -8.384615384615385) + r83 = convert(T, 5.769230769230769) + r82 = convert(T, -1.3846153846153846) + OwrenZen5ConstantCache(a21, a31, a32, a41, a42, a51, a52, a53, + a54, a61, a62, a63, a64, a65, a71, a72, a73, + a74, a75, a76, a81, a83, a84, a85, a86, a87, + c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, + btilde6, btilde7, + r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, + r43, r42, r55, r54, r53, r52, r65, r64, r63, + r62, r75, r74, r73, r72, r85, r84, r83, r82) +end + +function OwrenZen5ConstantCache(T, T2) + a21 = convert(T, 1 // 6) + a31 = convert(T, 1 // 16) + a32 = convert(T, 3 // 16) + a41 = convert(T, 1 // 4) + a42 = convert(T, -3 // 4) + a43 = convert(T, 1) + a51 = convert(T, -3 // 4) + a52 = convert(T, 15 // 4) + a53 = convert(T, -3) + a54 = convert(T, 1 // 2) + a61 = convert(T, 369 // 1372) + a62 = convert(T, -243 // 343) + a63 = convert(T, 297 // 343) + a64 = convert(T, 1485 // 9604) + a65 = convert(T, 297 // 4802) + a71 = convert(T, -133 // 4512) + a72 = convert(T, 1113 // 6016) + a73 = convert(T, 7945 // 16544) + a74 = convert(T, -12845 // 24064) + a75 = convert(T, -315 // 24064) + a76 = convert(T, 156065 // 198528) + a81 = convert(T, 83 // 945) + a83 = convert(T, 248 // 825) + a84 = convert(T, 41 // 180) + a85 = convert(T, 1 // 36) + a86 = convert(T, 2401 // 38610) + a87 = convert(T, 6016 // 20475) + c1 = convert(T2, 1 // 6) + c2 = convert(T2, 1 // 4) + c3 = convert(T2, 1 // 2) + c4 = convert(T2, 1 // 2) + c5 = convert(T2, 9 // 14) + c6 = convert(T2, 7 // 8) + # b1 = convert(T,-1//9) + # b3 = convert(T,40//33) + # b4 = convert(T,-7//4) + # b5 = convert(T,-1//12) + # b6 = convert(T,343//198) + btilde1 = convert(T, -188 // 945) + btilde3 = convert(T, 752 // 825) + btilde4 = convert(T, -89 // 45) + btilde5 = convert(T, -1 // 9) + btilde6 = convert(T, 32242 // 19305) + btilde7 = convert(T, -6016 // 20475) + r15 = convert(T, 596 // 315) + r14 = convert(T, -4969 // 819) + r13 = convert(T, 17893 // 2457) + r12 = convert(T, -3292 // 819) + r35 = convert(T, -1984 // 275) + r34 = convert(T, 1344 // 65) + r33 = convert(T, -43568 // 2145) + r32 = convert(T, 5112 // 715) + r45 = convert(T, 118 // 15) + r44 = convert(T, -1465 // 78) + r43 = convert(T, 3161 // 234) + r42 = convert(T, -123 // 52) + r55 = convert(T, 2) + r54 = convert(T, -413 // 78) + r53 = convert(T, 1061 // 234) + r52 = convert(T, -63 // 52) + r65 = convert(T, -9604 // 6435) + r64 = convert(T, 2401 // 1521) + r63 = convert(T, 60025 // 50193) + r62 = convert(T, -40817 // 33462) + r75 = convert(T, -48128 // 6825) + r74 = convert(T, 96256 // 5915) + r73 = convert(T, -637696 // 53235) + r72 = convert(T, 18048 // 5915) + r85 = convert(T, 4) + r84 = convert(T, -109 // 13) + r83 = convert(T, 75 // 13) + r82 = convert(T, -18 // 13) + OwrenZen5ConstantCache(a21, a31, a32, a41, a42, a51, a52, a53, + a54, a61, a62, a63, a64, a65, a71, a72, a73, + a74, a75, a76, a81, a83, a84, a85, a86, a87, + c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, + btilde6, btilde7, + r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, + r43, r42, r55, r54, r53, r52, r65, r64, r63, + r62, r75, r74, r73, r72, r85, r84, r83, r82) +end + +struct Tsit5ConstantCache <: OrdinaryDiffEqConstantCache end +struct Tsit5ConstantCacheActual{T, T2} + c1::T2 + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T +end + +@fold function Tsit5ConstantCacheActual(::Type{T}, + ::Type{T2}) where {T <: CompiledFloats, + T2 <: CompiledFloats} + c1 = convert(T2, 0.161) + c2 = convert(T2, 0.327) + c3 = convert(T2, 0.9) + c4 = convert(T2, 0.9800255409045097) + c5 = convert(T2, 1) + c6 = convert(T2, 1) + a21 = convert(T, 0.161) + a31 = convert(T, -0.008480655492356989) + a32 = convert(T, 0.335480655492357) + a41 = convert(T, 2.8971530571054935) + a42 = convert(T, -6.359448489975075) + a43 = convert(T, 4.3622954328695815) + a51 = convert(T, 5.325864828439257) + a52 = convert(T, -11.748883564062828) + a53 = convert(T, 7.4955393428898365) + a54 = convert(T, -0.09249506636175525) + a61 = convert(T, 5.86145544294642) + a62 = convert(T, -12.92096931784711) + a63 = convert(T, 8.159367898576159) + a64 = convert(T, -0.071584973281401) + a65 = convert(T, -0.028269050394068383) + a71 = convert(T, 0.09646076681806523) + a72 = convert(T, 0.01) + a73 = convert(T, 0.4798896504144996) + a74 = convert(T, 1.379008574103742) + a75 = convert(T, -3.290069515436081) + a76 = convert(T, 2.324710524099774) + # b1 = convert(T,0.09468075576583945) + # b2 = convert(T,0.009183565540343254) + # b3 = convert(T,0.4877705284247616) + # b4 = convert(T,1.234297566930479) + # b5 = convert(T,-2.7077123499835256) + # b6 = convert(T,1.866628418170587) + # b7 = convert(T,0.015151515151515152) + btilde1 = convert(T, -0.00178001105222577714) + btilde2 = convert(T, -0.0008164344596567469) + btilde3 = convert(T, 0.007880878010261995) + btilde4 = convert(T, -0.1447110071732629) + btilde5 = convert(T, 0.5823571654525552) + btilde6 = convert(T, -0.45808210592918697) + btilde7 = convert(T, 0.015151515151515152) + + Tsit5ConstantCacheActual( + c1, c2, c3, c4, c5, c6, a21, a31, a32, a41, a42, a43, a51, a52, + a53, + a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, + btilde1, + btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) +end + +@fold function Tsit5ConstantCacheActual(::Type{T}, ::Type{T2}) where {T, T2} + c1 = convert(T2, 161 // 1000) + c2 = convert(T2, 327 // 1000) + c3 = convert(T2, 9 // 10) + c4 = convert(T2, + big".9800255409045096857298102862870245954942137979563024768854764293221195950761080302604") + c5 = convert(T2, 1) + c6 = convert(T2, 1) + a21 = convert(T, 161 // 1000) + a31 = convert(T, + big"-.8480655492356988544426874250230774675121177393430391537369234245294192976164141156943e-2") + a32 = convert(T, + big".3354806554923569885444268742502307746751211773934303915373692342452941929761641411569") + a41 = convert(T, + big"2.897153057105493432130432594192938764924887287701866490314866693455023795137503079289") + a42 = convert(T, + big"-6.359448489975074843148159912383825625952700647415626703305928850207288721235210244366") + a43 = convert(T, + big"4.362295432869581411017727318190886861027813359713760212991062156752264926097707165077") + a51 = convert(T, + big"5.325864828439256604428877920840511317836476253097040101202360397727981648835607691791") + a52 = convert(T, + big"-11.74888356406282787774717033978577296188744178259862899288666928009020615663593781589") + a53 = convert(T, + big"7.495539342889836208304604784564358155658679161518186721010132816213648793440552049753") + a54 = convert(T, + big"-.9249506636175524925650207933207191611349983406029535244034750452930469056411389539635e-1") + a61 = convert(T, + big"5.861455442946420028659251486982647890394337666164814434818157239052507339770711679748") + a62 = convert(T, + big"-12.92096931784710929170611868178335939541780751955743459166312250439928519268343184452") + a63 = convert(T, + big"8.159367898576158643180400794539253485181918321135053305748355423955009222648673734986") + a64 = convert(T, + big"-.7158497328140099722453054252582973869127213147363544882721139659546372402303777878835e-1") + a65 = convert(T, + big"-.2826905039406838290900305721271224146717633626879770007617876201276764571291579142206e-1") + a71 = convert(T, + big".9646076681806522951816731316512876333711995238157997181903319145764851595234062815396e-1") + a72 = convert(T, 1 // 100) + a73 = convert(T, + big".4798896504144995747752495322905965199130404621990332488332634944254542060153074523509") + a74 = convert(T, + big"1.379008574103741893192274821856872770756462643091360525934940067397245698027561293331") + a75 = convert(T, + big"-3.290069515436080679901047585711363850115683290894936158531296799594813811049925401677") + a76 = convert(T, + big"2.324710524099773982415355918398765796109060233222962411944060046314465391054716027841") + # b1 = convert(T,big".9468075576583945807478876255758922856117527357724631226139574065785592789071067303271e-1") + # b2 = convert(T,big".9183565540343253096776363936645313759813746240984095238905939532922955247253608687270e-2") + # b3 = convert(T,big".4877705284247615707855642599631228241516691959761363774365216240304071651579571959813") + # b4 = convert(T,big"1.234297566930478985655109673884237654035539930748192848315425833500484878378061439761") + # b5 = convert(T,big"-2.707712349983525454881109975059321670689605166938197378763992255714444407154902012702") + # b6 = convert(T,big"1.866628418170587035753719399566211498666255505244122593996591602841258328965767580089") + # b7 = convert(T,1//66) + btilde1 = convert(T, + big"-1.780011052225771443378550607539534775944678804333659557637450799792588061629796e-03") + btilde2 = convert(T, + big"-8.164344596567469032236360633546862401862537590159047610940604670770447527463931e-04") + btilde3 = convert(T, + big"7.880878010261996010314727672526304238628733777103128603258129604952959142646516e-03") + btilde4 = convert(T, + big"-1.44711007173262907537165147972635116720922712343167677619514233896760819649515e-01") + btilde5 = convert(T, + big"5.823571654525552250199376106520421794260781239567387797673045438803694038950012e-01") + btilde6 = convert(T, + big"-4.580821059291869466616365188325542974428047279788398179474684434732070620889539e-01") + btilde7 = convert(T, 1 // 66) + + Tsit5ConstantCacheActual( + c1, c2, c3, c4, c5, c6, a21, a31, a32, a41, a42, a43, a51, a52, + a53, + a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, + btilde1, + btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) +end + +""" +Coefficients for the polynomial +bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... + +These are the coefficients of the expanded form of the polynomials from + +Runge–Kutta pairs of order 5(4) satisfying only the first column +simplifying assumption + +Ch. Tsitouras +""" +@fold function Tsit5Interp(::Type{T}) where {T <: CompiledFloats} + r11 = convert(T, 1.0) + r12 = convert(T, -2.763706197274826) + r13 = convert(T, 2.9132554618219126) + r14 = convert(T, -1.0530884977290216) + + r22 = convert(T, 0.13169999999999998) + r23 = convert(T, -0.2234) + r24 = convert(T, 0.1017) + + r32 = convert(T, 3.9302962368947516) + r33 = convert(T, -5.941033872131505) + r34 = convert(T, 2.490627285651253) + + r42 = convert(T, -12.411077166933676) + r43 = convert(T, 30.33818863028232) + r44 = convert(T, -16.548102889244902) + + r52 = convert(T, 37.50931341651104) + r53 = convert(T, -88.1789048947664) + r54 = convert(T, 47.37952196281928) + + r62 = convert(T, -27.896526289197286) + r63 = convert(T, 65.09189467479366) + r64 = convert(T, -34.87065786149661) + + r72 = convert(T, 1.5) + r73 = convert(T, -4) + r74 = convert(T, 2.5) + + return r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, + r62, r63, r64, r72, r73, r74 +end + +""" +Coefficients for the polynomial +bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... + +These are the coefficients of the expanded form of the polynomials from + +Runge–Kutta pairs of order 5(4) satisfying only the first column +simplifying assumption + +Ch. Tsitouras +""" +@fold function Tsit5Interp(::Type{T}) where {T} + r11 = convert(T, big"0.999999999999999974283372471559910888475488471328") + r12 = convert(T, big"-2.763706197274825911336735930481400260916070804192") + r13 = convert(T, big"2.91325546182191274375068099306808") + r14 = convert(T, -1.0530884977290216) + + r22 = convert(T, big"0.13169999999999999727") + r23 = convert(T, big"-0.22339999999999999818") + r24 = convert(T, 0.1017) + + r32 = convert(T, big"3.93029623689475152850687446709813398") + r33 = convert(T, big"-5.94103387213150473470249202589458001") + r34 = convert(T, big"2.490627285651252793") + + r42 = convert(T, big"-12.411077166933676983734381540685453484102414134010752") + r43 = convert(T, big"30.3381886302823215981729903691836576") + r44 = convert(T, big"-16.54810288924490272") + + r52 = convert(T, big"37.50931341651103919496903965334519631242339792120440212") + r53 = convert(T, big"-88.1789048947664011014276693541209817") + r54 = convert(T, big"47.37952196281928122") + + r62 = convert(T, big"-27.896526289197287805948263144598643896") + r63 = convert(T, big"65.09189467479367152629021928716553658") + r64 = convert(T, big"-34.87065786149660974") + + r72 = convert(T, 1.5) + r73 = convert(T, -4) + r74 = convert(T, 2.5) + + return r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, + r62, r63, r64, r72, r73, r74 +end + +struct BS5ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + c1::T2 + c2::T2 + c3::T2 + c4::T2 + c5::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + a81::T + a83::T + a84::T + a85::T + a86::T + a87::T + bhat1::T + bhat3::T + bhat4::T + bhat5::T + bhat6::T + btilde1::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + btilde8::T + c6::T2 + c7::T2 + c8::T2 + a91::T + a92::T + a93::T + a94::T + a95::T + a96::T + a97::T + a98::T + a101::T + a102::T + a103::T + a104::T + a105::T + a106::T + a107::T + a108::T + a109::T + a111::T + a112::T + a113::T + a114::T + a115::T + a116::T + a117::T + a118::T + a119::T + a1110::T + r016::T + r015::T + r014::T + r013::T + r012::T + r036::T + r035::T + r034::T + r033::T + r032::T + r046::T + r045::T + r044::T + r043::T + r042::T + r056::T + r055::T + r054::T + r053::T + r052::T + r066::T + r065::T + r064::T + r063::T + r062::T + r076::T + r075::T + r074::T + r073::T + r072::T + r086::T + r085::T + r084::T + r083::T + r082::T + r096::T + r095::T + r094::T + r093::T + r106::T + r105::T + r104::T + r103::T + r102::T + r116::T + r115::T + r114::T + r113::T + r112::T +end + +""" +An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine +Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 +""" +function BS5ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + c1 = convert(T2, 0.16666666666666666) + c2 = convert(T2, 0.2222222222222222) + c3 = convert(T2, 0.42857142857142855) + c4 = convert(T2, 0.6666666666666666) + c5 = convert(T2, 0.75) + + a21 = convert(T, 0.16666666666666666) + a31 = convert(T, 0.07407407407407407) + a32 = convert(T, 0.14814814814814814) + a41 = convert(T, 0.13338192419825073) + a42 = convert(T, -0.47230320699708456) + a43 = convert(T, 0.7674927113702624) + a51 = convert(T, 0.22895622895622897) + a52 = convert(T, -0.36363636363636365) + a53 = convert(T, 0.2937062937062937) + a54 = convert(T, 0.5076405076405076) + a61 = convert(T, 0.026500355113636364) + a62 = convert(T, 0.23011363636363635) + a63 = convert(T, 0.10772747760052448) + a64 = convert(T, 0.1602190777972028) + a65 = convert(T, 0.225439453125) + a71 = convert(T, 0.18159821692916506) + a72 = convert(T, -0.38707982536247293) + a73 = convert(T, 0.41288268560074054) + a74 = convert(T, 0.6409913191253497) + a75 = convert(T, -1.0121439383514517) + a76 = convert(T, 1.1637515420586695) + a81 = convert(T, 0.07279265873015874) + a83 = convert(T, 0.28662437773692473) + a84 = convert(T, 0.19513621794871794) + a85 = convert(T, 0.008638392857142857) + a86 = convert(T, 0.3595655806182122) + a87 = convert(T, 0.07724277210884353) + + bhat1 = convert(T, -0.00234375) + bhat3 = convert(T, 0.0103760754048583) + bhat4 = convert(T, -0.016490384615384615) + bhat5 = convert(T, 0.018984375) + bhat6 = convert(T, -0.010526315789473684) + # btilde1=convert(T,0.07084476451760402) + # btilde2=convert(T,0) + # btilde3=convert(T,0.2956730769230769) + # btilde4=convert(T,0.17965747482208388) + # btilde5=convert(T,0.029861111111111113) + # btilde6=convert(T,0.3462886755067825) + # btilde7=convert(T,0.07176240133870539) + btilde1 = convert(T, -0.0019478942125547064) + btilde3 = convert(T, 0.009048699186152193) + btilde4 = convert(T, -0.015478743126634073) + btilde5 = convert(T, 0.021222718253968254) + btilde6 = convert(T, -0.013276905111429694) + btilde7 = convert(T, -0.005480370770138146) + btilde8 = convert(T, 0.005912495780636172) + c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = BS5Interp( + T, + T2) + r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = BS5Interp_polyweights(T) + BS5ConstantCache(c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, + a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, + btilde4, btilde5, btilde6, btilde7, btilde8, c6, c7, c8, a91, a92, a93, + a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, + a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, + a1110, r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, + r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, + r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, + r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, + r114, r113, r112) +end + +""" +An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine +Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 +""" +function BS5ConstantCache(T::Type, T2::Type) + c1 = convert(T2, 1 // 6) + c2 = convert(T2, 2 // 9) + c3 = convert(T2, 3 // 7) + c4 = convert(T2, 2 // 3) + c5 = convert(T2, 3 // 4) + + a21 = convert(T, 1 // 6) + a31 = convert(T, 2 // 27) + a32 = convert(T, 4 // 27) + a41 = convert(T, 183 // 1372) + a42 = convert(T, -162 // 343) + a43 = convert(T, 1053 // 1372) + a51 = convert(T, 68 // 297) + a52 = convert(T, -4 // 11) + a53 = convert(T, 42 // 143) + a54 = convert(T, 1960 // 3861) + a61 = convert(T, 597 // 22528) + a62 = convert(T, 81 // 352) + a63 = convert(T, 63099 // 585728) + a64 = convert(T, 58653 // 366080) + a65 = convert(T, 4617 // 20480) + a71 = convert(T, 174197 // 959244) + a72 = convert(T, -30942 // 79937) + a73 = convert(T, 8152137 // 19744439) + a74 = convert(T, 666106 // 1039181) + a75 = convert(T, -29421 // 29068) + a76 = convert(T, 482048 // 414219) + a81 = convert(T, 587 // 8064) + a83 = convert(T, 4440339 // 15491840) + a84 = convert(T, 24353 // 124800) + a85 = convert(T, 387 // 44800) + a86 = convert(T, 2152 // 5985) + a87 = convert(T, 7267 // 94080) + + bhat1 = convert(T, -3 // 1280) + bhat3 = convert(T, 6561 // 632320) + bhat4 = convert(T, -343 // 20800) + bhat5 = convert(T, 243 // 12800) + bhat6 = convert(T, -1 // 95) + # btilde1=convert(T,2479//34992) + # btilde2=convert(T,0) + # btilde3=convert(T,123//416) + # btilde4=convert(T,612941//3411720) + # btilde5=convert(T,43//1440) + # btilde6=convert(T,2272//6561) + # btilde7=convert(T,79937//1113912) + btilde1 = convert(T, -3817 // 1959552) + btilde3 = convert(T, 140181 // 15491840) + btilde4 = convert(T, -4224731 // 272937600) + btilde5 = convert(T, 8557 // 403200) + btilde6 = convert(T, -57928 // 4363065) + btilde7 = convert(T, -23930231 // 4366535040) + btilde8 = convert(T, 3293 // 556956) + c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = BS5Interp( + T, + T2) + r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = BS5Interp_polyweights(T) + BS5ConstantCache(c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, + a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, + btilde4, btilde5, btilde6, btilde7, btilde8, c6, c7, c8, a91, a92, a93, + a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, + a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, + a1110, r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, + r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, + r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, + r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, + r114, r113, r112) +end + +""" +An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine +Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 + +Used in the lazy construction of the dense output + +k9, k10, k11 are not computed until called in the dense routine +""" +function BS5Interp(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + c6 = convert(T2, 0.5) + c7 = convert(T2, 0.8333333333333334) + c8 = convert(T2, 0.1111111111111111) + a91 = convert(T, 0.07405598958333333) + a92 = convert(T, 0) + a93 = convert(T, 0.28964485093442743) + a94 = convert(T, 0.12839214966168092) + a95 = convert(T, -0.003779296875) + a96 = convert(T, 0.014230019493177388) + a97 = convert(T, -0.03379371279761905) + a98 = convert(T, 0.03125) + a101 = convert(T, -0.06358724036162344) + a102 = convert(T, 0.5742461924818869) + a103 = convert(T, -0.06365063007249953) + a104 = convert(T, 0.043159777438314964) + a105 = convert(T, 0.8370112883898733) + a106 = convert(T, -0.34045447246719235) + a107 = convert(T, 0.04926503818334922) + a108 = convert(T, -0.006882677669165967) + a109 = convert(T, -0.19577394258960973) + a111 = convert(T, 0.0636090772400987) + a112 = convert(T, 0.01057854182854183) + a113 = convert(T, 0.06600100945670531) + a114 = convert(T, 0.02048391555358402) + a115 = convert(T, 0.003682270330219549) + a116 = convert(T, 0.155258632271002) + a117 = convert(T, -0.08509702513818027) + a118 = convert(T, 0.1) + a119 = convert(T, -0.1) + a1110 = convert(T, -0.12340531043086005) + + return c6, + c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, + a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, + a1110 +end + +""" +An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine +Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 + +Used in the lazy construction of the dense output + +k9, k10, k11 are not computed until called in the dense routine +""" +function BS5Interp(T::Type, T2::Type) + c6 = convert(T2, 1 // 2) + c7 = convert(T2, 5 // 6) + c8 = convert(T2, 1 // 9) + a91 = convert(T, 455 // 6144) + a92 = convert(T, 0) + a93 = convert(T, 10256301 // 35409920) + a94 = convert(T, 2307361 // 17971200) + a95 = convert(T, -387 // 102400) + a96 = convert(T, 73 // 5130) + a97 = convert(T, -7267 // 215040) + a98 = convert(T, 1 // 32) + a101 = convert(T, -837888343715 // 13176988637184) + a102 = convert(T, 30409415 // 52955362) + a103 = convert(T, -48321525963 // 759168069632) + a104 = convert(T, 8530738453321 // 197654829557760) + a105 = convert(T, 1361640523001 // 1626788720640) + a106 = convert(T, -13143060689 // 38604458898) + a107 = convert(T, 18700221969 // 379584034816) + a108 = convert(T, -5831595 // 847285792) + a109 = convert(T, -5183640 // 26477681) + a111 = convert(T, 98719073263 // 1551965184000) + a112 = convert(T, 1307 // 123552) + a113 = convert(T, 4632066559387 // 70181753241600) + a114 = convert(T, 7828594302389 // 382182512025600) + a115 = convert(T, 40763687 // 11070259200) + a116 = convert(T, 34872732407 // 224610586200) + a117 = convert(T, -2561897 // 30105600) + a118 = convert(T, 1 // 10) + a119 = convert(T, -1 // 10) + a1110 = convert(T, -1403317093 // 11371610250) + + return c6, + c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, + a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, + a1110 +end + +""" +Coefficients for the polynomial +bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... + +These coefficients are taken from RKSuite + +Note that RKSuite has an error: r081 should be 0 +and r011 should be 1. This is pretty easy to spot +since the first order interpolation is linear from y₀. +""" +function BS5Interp_polyweights(T::Type{<:CompiledFloats}) + r016 = convert(T, -11.547607240534195) + r015 = convert(T, 36.89579791207878) + r014 = convert(T, -45.470343197183475) + r013 = convert(T, 27.298136302807084) + r012 = convert(T, -8.103191118438032) + + r036 = convert(T, -27.245925284262768) + r035 = convert(T, 74.85879078710211) + r034 = convert(T, -72.2759709558427) + r033 = convert(T, 28.38602193195626) + r032 = convert(T, -3.4362921012159933) + + r046 = convert(T, -14.307769126529058) + r045 = convert(T, 38.240038148817945) + r044 = convert(T, -35.469854845413806) + r043 = convert(T, 13.060399314592578) + r042 = convert(T, -1.3276772735189397) + + r056 = convert(T, -0.7296779223862557) + r055 = convert(T, 1.9817123385873385) + r054 = convert(T, -1.964240395021645) + r053 = convert(T, 0.8847786781120115) + r052 = convert(T, -0.16393430643430643) + + r066 = convert(T, 19.121088881250603) + r065 = convert(T, -65.9928405785889) + r064 = convert(T, 77.4690381021765) + r063 = convert(T, -34.163041154825144) + r062 = convert(T, 3.9253203306051474) + + r076 = convert(T, -14.676126700680273) + r075 = convert(T, 42.17455357142857) + r074 = convert(T, -42.4062818877551) + r073 = convert(T, 16.83892431972789) + r072 = convert(T, -1.853826530612245) + + r086 = convert(T, 19.453125) + r085 = convert(T, -54.359375) + r084 = convert(T, 53.671875) + r083 = convert(T, -21.078125) + r082 = convert(T, 2.3125) + + r096 = convert(T, 18.333333333333332) + r095 = convert(T, -39) + r094 = convert(T, 23) + r093 = convert(T, -2.3333333333333335) + + r106 = convert(T, -23.400440940191388) + r105 = convert(T, 70.20132282057416) + r104 = convert(T, -73.55422182095978) + r103 = convert(T, 30.106238940962648) + r102 = convert(T, -3.3528990003856314) + + r116 = convert(T, 35) + r115 = convert(T, -105) + r114 = convert(T, 117) + r113 = convert(T, -59) + r112 = convert(T, 12) + + return r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, + r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, + r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, + r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 +end + +""" +Coefficients for the polynomial +bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... + +These coefficients are taken from RKSuite + +Note that RKSuite has an error: r081 should be 0 +and r011 should be 1. This is pretty easy to spot +since the first order interpolation is linear from y₀. +""" +function BS5Interp_polyweights(T::Type) + r016 = convert(T, -12134338393 // 1050809760) + r015 = convert(T, 12923488183 // 350269920) + r014 = convert(T, -2722545893 // 59875200) + r013 = convert(T, 35856435071 // 1313512200) + r012 = convert(T, -3547880131 // 437837400) + + r036 = convert(T, -33197340367 // 1218433216) + r035 = convert(T, 65150312289 // 870309440) + r034 = convert(T, -27096444225 // 374902528) + r033 = convert(T, 4323308999 // 152304152) + r032 = convert(T, -1046723109 // 304608304) + + r046 = convert(T, -284800997201 // 19905339168) + r045 = convert(T, 6343174409579 // 165877826400) + r044 = convert(T, -201150852119 // 5671036800) + r043 = convert(T, 3249645975331 // 248816739600) + r042 = convert(T, -55058055073 // 41469456600) + + r056 = convert(T, -540919 // 741312) + r055 = convert(T, 85695583 // 43243200) + r054 = convert(T, -2903933 // 1478400) + r053 = convert(T, 3586937 // 4054050) + r052 = convert(T, -1772261 // 10810800) + + r066 = convert(T, 7157998304 // 374350977) + r065 = convert(T, -41174140576 // 623918295) + r064 = convert(T, 413114104 // 5332635) + r063 = convert(T, -9134977024 // 267393555) + r062 = convert(T, 2449079168 // 623918295) + + r076 = convert(T, -138073 // 9408) + r075 = convert(T, 94471 // 2240) + r074 = convert(T, -1329861 // 31360) + r073 = convert(T, 792103 // 47040) + r072 = convert(T, -7267 // 3920) + + r086 = convert(T, 1245 // 64) + r085 = convert(T, -3479 // 64) + r084 = convert(T, 3435 // 64) + r083 = convert(T, -1349 // 64) + r082 = convert(T, 37 // 16) + + r096 = convert(T, 55 // 3) + r095 = convert(T, -39) + r094 = convert(T, 23) + r093 = convert(T, -7 // 3) + + r106 = convert(T, -1774004627 // 75810735) + r105 = convert(T, 1774004627 // 25270245) + r104 = convert(T, -26477681 // 359975) + r103 = convert(T, 11411880511 // 379053675) + r102 = convert(T, -423642896 // 126351225) + + r116 = convert(T, 35) + r115 = convert(T, -105) + r114 = convert(T, 117) + r113 = convert(T, -59) + r112 = convert(T, 12) + + return r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, + r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, + r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, + r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 +end + +struct DP5ConstantCache <: OrdinaryDiffEqConstantCache end +struct DP5ConstantCacheActual{T, T2} + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a73::T + a74::T + a75::T + a76::T + btilde1::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + c1::T2 + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + d1::T + d3::T + d4::T + d5::T + d6::T + d7::T +end + +@fold function DP5ConstantCacheActual(::Type{T}, + ::Type{T2}) where {T <: CompiledFloats, + T2 <: + CompiledFloats} + a21 = convert(T, 0.2) + a31 = convert(T, 0.075) + a32 = convert(T, 0.225) + a41 = convert(T, 0.9777777777777777) + a42 = convert(T, -3.7333333333333334) + a43 = convert(T, 3.5555555555555554) + a51 = convert(T, 2.9525986892242035) + a52 = convert(T, -11.595793324188385) + a53 = convert(T, 9.822892851699436) + a54 = convert(T, -0.2908093278463649) + a61 = convert(T, 2.8462752525252526) + a62 = convert(T, -10.757575757575758) + a63 = convert(T, 8.906422717743473) + a64 = convert(T, 0.2784090909090909) + a65 = convert(T, -0.2735313036020583) + a71 = convert(T, 0.09114583333333333) + a73 = convert(T, 0.44923629829290207) + a74 = convert(T, 0.6510416666666666) + a75 = convert(T, -0.322376179245283) + a76 = convert(T, 0.13095238095238096) + # b1 = convert(T,0.08991319444444444) + # b3 = convert(T,0.4534890685834082) + # b4 = convert(T,0.6140625) + # b5 = convert(T,-0.2715123820754717) + # b6 = convert(T,0.08904761904761904) + # b7 = convert(T,0.025) + btilde1 = convert(T, -0.0012326388888888888) + btilde3 = convert(T, 0.0042527702905061394) + btilde4 = convert(T, -0.03697916666666667) + btilde5 = convert(T, 0.05086379716981132) + btilde6 = convert(T, -0.0419047619047619) + btilde7 = convert(T, 0.025) + c1 = convert(T2, 0.2) + c2 = convert(T2, 0.3) + c3 = convert(T2, 0.8) + c4 = convert(T2, 0.8888888888888888) + c5 = convert(T2, 1) + c6 = convert(T2, 1) + d1, d3, d4, d5, d6, d7 = DP5_dense_ds(T) + DP5ConstantCacheActual(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, + a64, + a65, a71, a73, a74, a75, a76, btilde1, btilde3, btilde4, btilde5, + btilde6, btilde7, c1, c2, c3, c4, c5, c6, d1, d3, d4, d5, d6, d7) +end + +@fold function DP5_dense_ds(::Type{T}) where {T <: CompiledFloats} + d1 = convert(T, -1.1270175653862835) + d3 = convert(T, 2.675424484351598) + d4 = convert(T, -5.685526961588504) + d5 = convert(T, 3.5219323679207912) + d6 = convert(T, -1.7672812570757455) + d7 = convert(T, 2.382468931778144) + return d1, d3, d4, d5, d6, d7 +end + +@fold function DP5ConstantCacheActual(::Type{T}, ::Type{T2}) where {T, T2} + a21 = convert(T, 1 // 5) + a31 = convert(T, 3 // 40) + a32 = convert(T, 9 // 40) + a41 = convert(T, 44 / 45) + a42 = convert(T, -56 // 15) + a43 = convert(T, 32 // 9) + a51 = convert(T, 19372 // 6561) + a52 = convert(T, -25360 // 2187) + a53 = convert(T, 64448 // 6561) + a54 = convert(T, -212 // 729) + a61 = convert(T, 9017 // 3168) + a62 = convert(T, -355 // 33) + a63 = convert(T, 46732 // 5247) + a64 = convert(T, 49 // 176) + a65 = convert(T, -5103 // 18656) + a71 = convert(T, 35 // 384) + a73 = convert(T, 500 // 1113) + a74 = convert(T, 125 // 192) + a75 = convert(T, -2187 // 6784) + a76 = convert(T, 11 // 84) + # b1 = convert(T,5179//57600) + # b3 = convert(T,7571//16695) + # b4 = convert(T,393//640) + # b5 = convert(T,-92097//339200) + # b6 = convert(T,187//2100) + # b7 = convert(T,1//40) + btilde1 = convert(T, -71 // 57600) + btilde3 = convert(T, 71 // 16695) + btilde4 = convert(T, -71 // 1920) + btilde5 = convert(T, 17253 // 339200) + btilde6 = convert(T, -22 // 525) + btilde7 = convert(T, 1 // 40) + c1 = convert(T2, 1 // 5) + c2 = convert(T2, 3 // 10) + c3 = convert(T2, 4 // 5) + c4 = convert(T2, 8 // 9) + c5 = convert(T2, 1) + c6 = convert(T2, 1) + d1, d3, d4, d5, d6, d7 = DP5_dense_ds(T) + DP5ConstantCacheActual(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, + a64, + a65, a71, a73, a74, a75, a76, btilde1, btilde3, btilde4, btilde5, + btilde6, btilde7, c1, c2, c3, c4, c5, c6, d1, d3, d4, d5, d6, d7) +end + +@fold function DP5_dense_ds(::Type{T}) where {T} + d1 = convert(T, -12715105075 // 11282082432) + d3 = convert(T, 87487479700 // 32700410799) + d4 = convert(T, -10690763975 // 1880347072) + d5 = convert(T, 701980252875 // 199316789632) + d6 = convert(T, -1453857185 // 822651844) + d7 = convert(T, 69997945 // 29380423) + return d1, d3, d4, d5, d6, d7 +end + +#= +function DP5_dense_bs(T) + b1 = convert(T,5179//57600) + b3 = convert(T,7571//16695) + b4 = convert(T,393//640) + b5 = convert(T,-92097//339200) + b6 = convert(T,187//2100) + b7 = convert(T,1//40) + return b1,b3,b4,b5,b6,b7 +end +=# + +""" +An Optimized Runge-Kutta method for the solution of Orbital Problems +by Z.A. Anastassi and T.E. Simos +Journal of Computational and Applied Mathematics, Volume 175, Issue 1, 1 March 2005, Pages 1 to 9. +""" +struct Anas5ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + b1::T + b3::T + b4::T + b5::T + b6::T +end + +function Anas5ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + a21 = convert(T, 0.1) + a31 = convert(T, -0.2222222222222222) + a32 = convert(T, 0.5555555555555556) + a41 = convert(T, 3.111111111111111) + a42 = convert(T, -4.444444444444444) + a43 = convert(T, 2.0) + a51 = convert(T, -1.409625) + a52 = convert(T, 2.1375) + a53 = convert(T, -0.2295) + a54 = convert(T, 0.401625) + a61 = convert(T, -4.0) + a62 = convert(T, 5.0) + a63 = convert(T, 0.0) + a64 = convert(T, 0.0) + a65 = convert(T, 0.0) + c2 = convert(T2, 0.1) + c3 = convert(T2, 0.3333333333333333) + c4 = convert(T2, 0.6666666666666667) + c5 = convert(T2, 0.9) + c6 = convert(T2, 1) + b1 = convert(T, 0.1064814814814815) + b3 = convert(T, 0.4632352941176471) + b4 = convert(T, 0.1607142857142857) + b5 = convert(T, 0.3112356053532524) + b6 = convert(T, -0.04166666666666667) + Anas5ConstantCache( + a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6) +end + +function Anas5ConstantCache(T, T2) + a21 = convert(T, 1 // 10) + a31 = convert(T, -2 // 9) + a32 = convert(T, 5 // 9) + a41 = convert(T, 28 // 9) + a42 = convert(T, -40 // 9) + a43 = convert(T, 2 // 1) + a51 = convert(T, -11277 // 8000) + a52 = convert(T, 171 // 80) + a53 = convert(T, -459 // 2000) + a54 = convert(T, 3213 // 8000) + a61 = convert(T, -4 // 1) + a62 = convert(T, 5 // 1) + a63 = convert(T, 0 // 1) + a64 = convert(T, 0 // 1) + a65 = convert(T, 0 // 1) + c2 = convert(T2, 1 // 10) + c3 = convert(T2, 1 // 3) + c4 = convert(T2, 2 // 3) + c5 = convert(T2, 9 // 10) + c6 = convert(T2, 1 // 1) + b1 = convert(T, 23 // 216) + b3 = convert(T, 63 // 136) + b4 = convert(T, 9 // 56) + b5 = convert(T, 1000 // 3213) + b6 = convert(T, -1 // 24) + Anas5ConstantCache( + a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6) +end + +struct PSRK4p7q6ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + + b1::T + b2::T + b3::T + b4::T + b5::T + b6::T + + c2::T1 + c3::T1 + c4::T1 + c5::T1 + c6::T1 +end + +function PSRK4p7q6ConstantCache(T::Type{<:CompiledFloats}, T1::Type{<:CompiledFloats}) + a21 = convert(T, 0.23593376536652) + a31 = convert(T, 0.34750735658424) + a32 = convert(T, -0.13561935398346) + a41 = convert(T, -0.20592852403227) + a42 = convert(T, 1.89179076622108) + a43 = convert(T, -0.89775024478958) + a51 = convert(T, -0.09435493281455) + a52 = convert(T, 1.75617141223762) + a53 = convert(T, -0.96707850476948) + a54 = convert(T, 0.06932825997989) + a61 = convert(T, 0.14157883255197) + a62 = convert(T, -1.17039696277833) + a63 = convert(T, 1.30579112376331) + a64 = convert(T, -2.20354136855289) + a65 = convert(T, 2.92656837501595) + + b1 = convert(T, 0.07078941627598) + b2 = convert(T, 0.87808570611881) + b3 = convert(T, -0.44887512239479) + b4 = convert(T, -0.44887512239479) + b5 = convert(T, 0.87808570611881) + b6 = convert(T, 0.07078941627598) + + c2 = convert(T1, 0.23593376536652) + c3 = convert(T1, 0.21188800260078) + c4 = convert(T1, 0.78811199739923) + c5 = convert(T1, 0.76406623463348) + c6 = convert(T1, 1.0) + + PSRK4p7q6ConstantCache( + a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, + b1, b2, b3, b4, b5, b6, + c2, c3, c4, c5, c6) +end + +struct PSRK3p6q5ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + + b1::T + b2::T + b3::T + b4::T + b5::T + + c2::T1 + c3::T1 + c4::T1 + c5::T1 +end + +function PSRK3p6q5ConstantCache(T::Type{<:CompiledFloats}, T1::Type{<:CompiledFloats}) + a21 = convert(T, 0.13502027922909) + a31 = convert(T, -0.47268213605237) + a32 = convert(T, 1.05980250415419) + a41 = convert(T, -1.21650460595689) + a42 = convert(T, 2.16217630216753) + a43 = convert(T, -0.37234592426536) + a51 = convert(T, 0.33274443036387) + a52 = convert(T, -0.20882668296587) + a53 = convert(T, 1.87865617737921) + a54 = convert(T, -1.00257392477721) + + b1 = convert(T, 0.04113894457092) + b2 = convert(T, 0.26732123194414) + b3 = convert(T, 0.86700906289955) + b4 = convert(T, -0.30547139552036) + b5 = convert(T, 0.13000215610576) + + c2 = convert(T1, 0.13502027922909) + c3 = convert(T1, 0.58712036810182) + c4 = convert(T1, 0.57332577194528) + c5 = convert(T1, 1.0) + + PSRK3p6q5ConstantCache( + a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + b1, b2, b3, b4, b5, + c2, c3, c4, c5) +end + +struct PSRK3p5q4ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + + b1::T + b2::T + b3::T + b4::T + + c2::T1 + c3::T1 + c4::T1 +end + +function PSRK3p5q4ConstantCache(T::Type, T1::Type) + a21 = T(3 // 8) + a31 = T(11 // 12) + a32 = T(-2 // 3) + a41 = T(-1 // 12) + a42 = T(11 // 6) + a43 = T(-3 // 4) + + b1 = T(1 // 9) + b2 = T(8 // 9) + b3 = T(-2 // 9) + b4 = T(2 // 9) + + c2 = T1(3 // 8) + c3 = T1(1 // 4) + c4 = T1(1) + + PSRK3p5q4ConstantCache( + a21, a31, a32, a41, a42, a43, + b1, b2, b3, b4, + c2, c3, c4) +end + +struct MSRK5ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a43::T + a51::T + a53::T + a54::T + a61::T + a63::T + a64::T + a65::T + a71::T + a73::T + a74::T + a75::T + a76::T + a81::T + a83::T + a84::T + a85::T + a86::T + a87::T + + b1::T # == a_{9i} ∀ i=1:8 + b4::T + b5::T + b6::T + b7::T + b8::T + + c2::T1 + c3::T1 + c4::T1 + c5::T1 + c6::T1 + c7::T1 + c8::T1 +end + +# Use rational numbers for testing. Define another function that defines the tab using floats. +function MSRK5ConstantCache(T::Type, T1::Type) + a21 = T(4 // 45) + a31 = T(1 // 30) + a32 = T(1 // 10) + a41 = T(1 // 20) + a43 = T(3 // 20) + a51 = T(1 // 2) + a53 = T(-15 // 8) + a54 = T(15 // 8) + a61 = T(-11 // 135) + a63 = T(23 // 45) + a64 = T(-2 // 27) + a65 = T(8 // 45) + a71 = T(5 // 108) + a73 = T(35 // 72) + a74 = T(-59 // 216) + a75 = T(-25 // 27) + a76 = T(3 // 2) + a81 = T(31 // 128) + a83 = T(-7563 // 4480) + a84 = T(233 // 112) + a85 = T(3461 // 2240) + a86 = T(-765 // 448) + a87 = T(153 // 320) + b1 = T(29 // 456) + b4 = T(11 // 38) + b5 = T(2 // 27) + b6 = T(11 // 40) + b7 = T(4 // 19) + b8 = T(224 // 2565) + c2 = T1(4 // 45) + c3 = T1(2 // 15) + c4 = T1(1 // 5) + c5 = T1(1 // 2) + c6 = T1(8 // 15) + c7 = T1(5 // 6) + c8 = T1(19 // 20) + + MSRK5ConstantCache( + a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, + a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, + c2, c3, c4, c5, c6, c7, c8) +end + +struct MSRK6ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache + a21::T + a32::T + a41::T + a43::T + a51::T + a53::T + a54::T + a61::T + a63::T + a64::T + a65::T + a71::T + a73::T + a74::T + a75::T + a76::T + a81::T + a83::T + a84::T + a85::T + a86::T + a87::T + + b1::T + b4::T + b5::T + b6::T + b7::T + b8::T + + c2::T1 + c3::T1 + c4::T1 + c5::T1 + c6::T1 + c7::T1 + c8::T1 +end + +function MSRK6ConstantCache(T::Type, T1::Type) + a21 = T(1 // 14) + a32 = T(1 // 7) + a41 = T(3 // 56) + a43 = T(9 // 56) + a51 = T(29 // 72) + a53 = T(-35 // 24) + a54 = T(14 // 9) + a61 = T(-17 // 56) + a63 = T(93 // 56) + a64 = T(-8 // 7) + a65 = T(3 // 7) + a71 = T(199 // 1372) + a73 = T(-195 // 196) + a74 = T(1259 // 784) + a75 = T(-3855 // 5488) + a76 = T(45 // 56) + a81 = T(4903 // 25596) + a83 = T(4487 // 2844) + a84 = T(-255101 // 102384) + a85 = T(33847 // 11376) + a86 = T(-94325 // 51192) + a87 = T(3773 // 6399) + b1 = T(16 // 243) + b4 = T(16807 // 53460) + b5 = T(53 // 300) + b6 = T(2401 // 12150) + b7 = T(2401 // 12150) + b8 = T(79 // 1650) + c2 = T1(1 // 14) + c3 = T1(1 // 7) + c4 = T1(3 // 14) + c5 = T1(1 // 2) + c6 = T1(9 // 14) + c7 = T1(6 // 7) + c8 = T1(1) + + MSRK6ConstantCache( + a21, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, + a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, + c3, c4, c5, c6, c7, c8) +end + +struct Stepanov5ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + + b1::T + # b2::T + b3::T + b4::T + b5::T + b6::T + + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + + c2::T1 + c3::T1 + c4::T1 + c5::T1 + c6::T1 +end + +# Use rational numbers for testing. Define another function that defines the tab using floats. +function Stepanov5ConstantCache(T::Type, T1::Type) + a21 = T(1 // 5) + a31 = T(21 // 338) + a32 = T(441 // 1690) + a41 = T(639 // 392) + a42 = T(-729 // 140) + a43 = T(1755 // 392) + a51 = T(4878991 // 1693440) + a52 = T(-16601 // 1792) + a53 = T(210067 // 28224) + a54 = T(-1469 // 17280) + a61 = T(13759919 // 4230954) + a62 = T(-2995 // 287) + a63 = T(507312091 // 61294590) + a64 = T(-22 // 405) + a65 = T(-7040 // 180687) + b1 = T(1441 // 14742) + # b2 = T(0) + b3 = T(114244 // 234927) + b4 = T(118 // 81) + b5 = T(-12800 // 4407) + b6 = T(41 // 22) + + btilde1 = T(-1 // 273) + btilde2 = T(0) + btilde3 = T(2197 // 174020) + btilde4 = T(-4 // 15) + btilde5 = T(1280 // 1469) + btilde6 = T(-33743 // 52712) + btilde7 = T(127 // 4792) + + c2 = T1(1 // 5) + c3 = T1(21 // 65) + c4 = T1(9 // 10) + c5 = T1(39 // 40) + c6 = T1(1 // 1) + + Stepanov5ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, + a64, a65, b1, b3, b4, b5, b6, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, + c2, c3, c4, c5, c6) +end + +struct SIR54ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + + b1::T + b2::T + b3::T + b4::T + b5::T + b6::T + + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 +end + +function SIR54ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + a21 = convert(T, 0.224991857145594237) + a31 = convert(T, 0.0891533610320671103) + a32 = convert(T, 0.238960211116888553) + a41 = convert(T, 1.30502239863058047) + a42 = convert(T, -5.50177549088639896) + a43 = convert(T, 5.14113139529316096) + a51 = convert(T, 1.76234012927544337) + a52 = convert(T, -7.44800428470202672) + a53 = convert(T, 6.70879999021246612) + a54 = convert(T, -0.0341377330357163063) + a61 = convert(T, 1.87412911619818746) + a62 = convert(T, -7.91467977711770718) + a63 = convert(T, 7.07985467092264069) + a64 = convert(T, -0.0244945338238275367) + a65 = convert(T, -0.0148094761792934300) + a71 = convert(T, 0.0986971498551664256) + a72 = convert(T, 0.00100729346874150652) + a73 = convert(T, 0.495118366873759549) + a74 = convert(T, 3.93767069618687179) + a75 = convert(T, -13.7395424087173685) + a76 = convert(T, 10.2070489023328292) + + b1 = convert(T, 0.0986971498551664256) + b2 = convert(T, 0.00100729346874150652) + b3 = convert(T, 0.495118366873759549) + b4 = convert(T, 3.93767069618687179) + b5 = convert(T, -13.7395424087173685) + b6 = convert(T, 10.2070489023328292) + + btilde1 = convert(T, 0.008811109678338494) + btilde2 = convert(T, 0.00011407564162559992) + btilde3 = convert(T, -0.029774887187671295) + btilde4 = convert(T, 9.643100938483734) + btilde5 = convert(T, -8.034112166420506) + btilde6 = convert(T, 6.31615797738573) + btilde7 = convert(T, -0.05) + + c2 = convert(T2, 0.224991857145594237) + c3 = convert(T2, 0.328113572148955663) + c4 = convert(T2, 0.944378303037342471) + c5 = convert(T2, 0.988998101750166470) + c6 = convert(T2, 1.0) + c7 = convert(T2, 1.0) + + SIR54ConstantCache( + a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, a71, a72, a73, a74, a75, a76, b1, b2, b3, b4, b5, b6, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, + c3, c4, c5, c6, c7) +end + +struct Alshina2ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + + b1::T + b2::T + b1tilde::T + + c2::T2 +end + +function Alshina2ConstantCache(T, T2) + a21 = convert(T, 0.6666666666666666) + + b1 = convert(T, 0.25) + b2 = convert(T, 0.75) + b1tilde = convert(T, 1.0) + + c2 = convert(T2, 0.666666666666666) + + Alshina2ConstantCache(a21, b1, b2, b1tilde, c2) +end + +struct Alshina3ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + # a31::T + a32::T + + b1::T + b2::T + b3::T + b2tilde::T + + c2::T2 + c3::T2 +end + +function Alshina3ConstantCache(T, T2) + a21 = convert(T, 0.5) + # a31 = convert(T, 0.0) + a32 = convert(T, 0.75) + + b1 = convert(T, 0.2222222222222222) + b2 = convert(T, 0.3333333333333333) + b3 = convert(T, 0.4444444444444444) + b2tilde = convert(T, 0.4444444444444444) + + c2 = convert(T2, 0.5) + c3 = convert(T2, 0.75) + + Alshina3ConstantCache(a21, a32, b1, b2, b3, b2tilde, c2, c3) +end + +struct Alshina6ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + + b1::T + # b2::T + # b3::T + # b4::T + b5::T + b6::T + b7::T + + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 +end + +function Alshina6ConstantCache(T, T2) + a21 = convert(T, 0.5714285714285714) + a31 = convert(T, 1.0267857142857142) + a32 = convert(T, -0.3125) + a41 = convert(T, 0.9349206349206349) + a42 = convert(T, 0.2777777777777778) + a43 = convert(T, -0.35555555555555557) + a51 = convert(T, 0.18002567144208434) + a52 = convert(T, 0.14737940683961614) + a53 = convert(T, 0.016070163293314288) + a54 = convert(T, -0.0670820393249937) + a61 = convert(T, -0.07979765856603138) + a62 = convert(T, 0.025290591998992584) + a63 = convert(T, -0.3516326202266813) + a64 = convert(T, 0.3207294901687516) + a65 = convert(T, 0.8090169943749475) + a71 = convert(T, 0.4988599356197352) + a72 = convert(T, -0.8633499941930429) + a73 = convert(T, 1.6778122846668349) + a74 = convert(T, -1.2682372542187894) + a75 = convert(T, -0.42705098312484235) + a76 = convert(T, 1.381966011250105) + + b1 = convert(T, 0.08333333333333333) + # b2 = convert(T, 0.0) + # b3 = convert(T, 0.0) + # b4 = convert(T, 0.0) + b5 = convert(T, 0.4166666666666667) + b6 = convert(T, 0.4166666666666667) + b7 = convert(T, 0.08333333333333333) + + c2 = convert(T2, 0.5714285714285714) + c3 = convert(T2, 0.7142857142857143) + c4 = convert(T2, 0.8571428571428571) + c5 = convert(T2, 0.276393202250021) + c6 = convert(T2, 0.7236067977499789) + c7 = convert(T2, 1.0) + + Alshina6ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, + a64, a65, a71, a72, a73, a74, a75, a76, + b1, b5, b6, b7, c2, c3, c4, c5, c6, c7) +end diff --git a/src/tableaus/rosenbrock_tableaus.jl b/src/tableaus/rosenbrock_tableaus.jl new file mode 100644 index 0000000000..493c67111a --- /dev/null +++ b/src/tableaus/rosenbrock_tableaus.jl @@ -0,0 +1,833 @@ +struct Rosenbrock23Tableau{T} + c₃₂::T + d::T +end + +function Rosenbrock23Tableau(T) + c₃₂ = convert(T, 6 + sqrt(2)) + d = convert(T, 1 / (2 + sqrt(2))) + Rosenbrock23Tableau(c₃₂, d) +end + +struct Rosenbrock32Tableau{T} + c₃₂::T + d::T +end + +function Rosenbrock32Tableau(T) + c₃₂ = convert(T, 6 + sqrt(2)) + d = convert(T, 1 / (2 + sqrt(2))) + Rosenbrock32Tableau(c₃₂, d) +end + +struct ROS3PTableau{T, T2} + a21::T + a31::T + a32::T + C21::T + C31::T + C32::T + b1::T + b2::T + b3::T + btilde1::T + btilde2::T + btilde3::T + gamma::T2 + c2::T2 + c3::T2 + d1::T + d2::T + d3::T +end + +function ROS3PTableau(T, T2) + gamma = convert(T, 1 / 2 + sqrt(3) / 6) + igamma = inv(gamma) + a21 = convert(T, igamma) + a31 = convert(T, igamma) + a32 = convert(T, 0) + C21 = convert(T, -igamma^2) + tmp = -igamma * (convert(T, 2) - convert(T, 1 / 2) * igamma) + C31 = -igamma * (convert(T, 1) - tmp) + C32 = tmp + tmp = igamma * (convert(T, 2 / 3) - convert(T, 1 / 6) * igamma) + b1 = igamma * (convert(T, 1) + tmp) + b2 = tmp + b3 = convert(T, 1 / 3) * igamma + # btilde1 = convert(T,2.113248654051871) + # btilde2 = convert(T,1.000000000000000) + # btilde3 = convert(T,0.4226497308103742) + btilde1 = b1 - convert(T, 2.113248654051871) + btilde2 = b2 - convert(T, 1.000000000000000) + btilde3 = b3 - convert(T, 0.4226497308103742) + c2 = convert(T, 1) + c3 = convert(T, 1) + d1 = convert(T, 0.7886751345948129) + d2 = convert(T, -0.2113248654051871) + d3 = convert(T, -1.077350269189626) + ROS3PTableau( + a21, a31, a32, C21, C31, C32, b1, b2, b3, btilde1, btilde2, btilde3, gamma, + c2, c3, d1, d2, d3) +end + +struct Rodas3Tableau{T, T2} + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + C21::T + C31::T + C32::T + C41::T + C42::T + C43::T + b1::T + b2::T + b3::T + b4::T + btilde1::T + btilde2::T + btilde3::T + btilde4::T + gamma::T2 + c2::T2 + c3::T2 + d1::T + d2::T + d3::T + d4::T +end + +function Rodas3Tableau(T, T2) + gamma = convert(T, 1 // 2) + a21 = convert(T, 0) + a31 = convert(T, 2) + a32 = convert(T, 0) + a41 = convert(T, 2) + a42 = convert(T, 0) + a43 = convert(T, 1) + C21 = convert(T, 4) + C31 = convert(T, 1) + C32 = convert(T, -1) + C41 = convert(T, 1) + C42 = convert(T, -1) + C43 = convert(T, -8 // 3) + b1 = convert(T, 2) + b2 = convert(T, 0) + b3 = convert(T, 1) + b4 = convert(T, 1) + btilde1 = convert(T, 0.0) + btilde2 = convert(T, 0.0) + btilde3 = convert(T, 0.0) + btilde4 = convert(T, 1.0) + c2 = convert(T, 0.0) + c3 = convert(T, 1.0) + c4 = convert(T, 1.0) + d1 = convert(T, 1 // 2) + d2 = convert(T, 3 // 2) + d3 = convert(T, 0) + d4 = convert(T, 0) + Rodas3Tableau(a21, a31, a32, a41, a42, a43, C21, C31, C32, C41, C42, C43, b1, b2, b3, + b4, btilde1, btilde2, btilde3, btilde4, gamma, c2, c3, d1, d2, d3, d4) +end + +struct Rodas3PTableau{T, T2} + a21::T + a41::T + a42::T + a43::T + C21::T + C31::T + C32::T + C41::T + C42::T + C43::T + C51::T + C52::T + C53::T + C54::T + gamma::T + c2::T2 + c3::T2 + d1::T + d2::T + d3::T + h21::T + h22::T + h23::T + h24::T + h25::T + h31::T + h32::T + h33::T + h34::T + h35::T + h2_21::T + h2_22::T + h2_23::T + h2_24::T + h2_25::T +end + +function Rodas3PTableau(T, T2) + gamma = convert(T, 1 // 3) + a21 = convert(T, 4.0 / 3.0) + a41 = convert(T, 2.90625) + a42 = convert(T, 3.375) + a43 = convert(T, 0.40625) + C21 = -convert(T, 4.0) + C31 = convert(T, 8.25) + C32 = convert(T, 6.75) + C41 = convert(T, 1.21875) + C42 = -convert(T, 5.0625) + C43 = -convert(T, 1.96875) + C51 = convert(T, 4.03125) + C52 = -convert(T, 15.1875) + C53 = -convert(T, 4.03125) + C54 = convert(T, 6.0) + c2 = convert(T2, 4.0 / 9.0) + c3 = convert(T2, 0.0) + d1 = convert(T, 1.0 / 3.0) + d2 = -convert(T, 1.0 / 9.0) + d3 = convert(T, 1.0) + h21 = convert(T, 1.78125) + h22 = convert(T, 6.75) + h23 = convert(T, 0.15625) + h24 = -convert(T, 6.0) + h25 = -convert(T, 1.0) + h31 = convert(T, 4.21875) + h32 = -convert(T, 15.1875) + h33 = -convert(T, 3.09375) + h34 = convert(T, 9.0) + h35 = convert(T, 0.0) + h2_21 = convert(T, 4.21875) + h2_22 = -convert(T, 2.025) + h2_23 = -convert(T, 1.63125) + h2_24 = -convert(T, 1.7) + h2_25 = -convert(T, 0.1) + Rodas3PTableau(a21, a41, a42, a43, + C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, + gamma, c2, c3, d1, d2, d3, + h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25) +end + +@ROS2(:tableau) + +@ROS23(:tableau) + +@ROS34PW(:tableau) + +@Rosenbrock4(:tableau) + +struct RodasTableau{T, T2} + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + C21::T + C31::T + C32::T + C41::T + C42::T + C43::T + C51::T + C52::T + C53::T + C54::T + C61::T + C62::T + C63::T + C64::T + C65::T + gamma::T + c2::T2 + c3::T2 + c4::T2 + d1::T + d2::T + d3::T + d4::T + h21::T + h22::T + h23::T + h24::T + h25::T + h31::T + h32::T + h33::T + h34::T + h35::T +end + +function Rodas4Tableau(T, T2) + gamma = convert(T, 1 // 4) + #BET2P=0.0317D0 + #BET3P=0.0635D0 + #BET4P=0.3438D0 + a21 = convert(T, 1.544000000000000) + a31 = convert(T, 0.9466785280815826) + a32 = convert(T, 0.2557011698983284) + a41 = convert(T, 3.314825187068521) + a42 = convert(T, 2.896124015972201) + a43 = convert(T, 0.9986419139977817) + a51 = convert(T, 1.221224509226641) + a52 = convert(T, 6.019134481288629) + a53 = convert(T, 12.53708332932087) + a54 = -convert(T, 0.6878860361058950) + C21 = -convert(T, 5.668800000000000) + C31 = -convert(T, 2.430093356833875) + C32 = -convert(T, 0.2063599157091915) + C41 = -convert(T, 0.1073529058151375) + C42 = -convert(T, 9.594562251023355) + C43 = -convert(T, 20.47028614809616) + C51 = convert(T, 7.496443313967647) + C52 = -convert(T, 10.24680431464352) + C53 = -convert(T, 33.99990352819905) + C54 = convert(T, 11.70890893206160) + C61 = convert(T, 8.083246795921522) + C62 = -convert(T, 7.981132988064893) + C63 = -convert(T, 31.52159432874371) + C64 = convert(T, 16.31930543123136) + C65 = -convert(T, 6.058818238834054) + + c2 = convert(T2, 0.386) + c3 = convert(T2, 0.21) + c4 = convert(T2, 0.63) + + d1 = convert(T, 0.2500000000000000) + d2 = -convert(T, 0.1043000000000000) + d3 = convert(T, 0.1035000000000000) + d4 = -convert(T, 0.03620000000000023) + + h21 = convert(T, 10.12623508344586) + h22 = -convert(T, 7.487995877610167) + h23 = -convert(T, 34.80091861555747) + h24 = -convert(T, 7.992771707568823) + h25 = convert(T, 1.025137723295662) + h31 = -convert(T, 0.6762803392801253) + h32 = convert(T, 6.087714651680015) + h33 = convert(T, 16.43084320892478) + h34 = convert(T, 24.76722511418386) + h35 = -convert(T, 6.594389125716872) + + RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, + gamma, c2, c3, c4, d1, d2, d3, d4, + h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) +end + +function Rodas42Tableau(T, T2) + gamma = convert(T, 1 // 4) + #BET2P=0.0317D0 + #BET3P=0.0047369D0 + #BET4P=0.3438D0 + a21 = convert(T, 1.402888400000000) + a31 = convert(T, 0.6581212688557198) + a32 = -convert(T, 1.320936088384301) + a41 = convert(T, 7.131197445744498) + a42 = convert(T, 16.02964143958207) + a43 = -convert(T, 5.561572550509766) + a51 = convert(T, 22.73885722420363) + a52 = convert(T, 67.38147284535289) + a53 = -convert(T, 31.21877493038560) + a54 = convert(T, 0.7285641833203814) + C21 = -convert(T, 5.104353600000000) + C31 = -convert(T, 2.899967805418783) + C32 = convert(T, 4.040399359702244) + C41 = -convert(T, 32.64449927841361) + C42 = -convert(T, 99.35311008728094) + C43 = convert(T, 49.99119122405989) + C51 = -convert(T, 76.46023087151691) + C52 = -convert(T, 278.5942120829058) + C53 = convert(T, 153.9294840910643) + C54 = convert(T, 10.97101866258358) + C61 = -convert(T, 76.29701586804983) + C62 = -convert(T, 294.2795630511232) + C63 = convert(T, 162.0029695867566) + C64 = convert(T, 23.65166903095270) + C65 = -convert(T, 7.652977706771382) + c2 = convert(T2, 0.3507221) + c3 = convert(T2, 0.2557041) + c4 = convert(T2, 0.6817790) + d1 = convert(T, 0.2500000000000000) + d2 = -convert(T, 0.06902209999999998) + d3 = -convert(T, 0.0009671999999999459) + d4 = -convert(T, 0.08797900000000025) + + h21 = -convert(T, 38.71940424117216) + h22 = -convert(T, 135.8025833007622) + h23 = convert(T, 64.51068857505875) + h24 = -convert(T, 4.192663174613162) + h25 = -convert(T, 2.531932050335060) + h31 = -convert(T, 14.99268484949843) + h32 = -convert(T, 76.30242396627033) + h33 = convert(T, 58.65928432851416) + h34 = convert(T, 16.61359034616402) + h35 = -convert(T, 0.6758691794084156) + + RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, + gamma, c2, c3, c4, d1, d2, d3, d4, + h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) +end + +function Rodas4PTableau(T, T2) + gamma = convert(T, 1 // 4) + #BET2P=0.D0 + #BET3P=c3*c3*(c3/6.d0-GAMMA/2.d0)/(GAMMA*GAMMA) + #BET4P=0.3438D0 + a21 = convert(T, 3) + a31 = convert(T, 1.831036793486759) + a32 = convert(T, 0.4955183967433795) + a41 = convert(T, 2.304376582692669) + a42 = -convert(T, 0.05249275245743001) + a43 = -convert(T, 1.176798761832782) + a51 = -convert(T, 7.170454962423024) + a52 = -convert(T, 4.741636671481785) + a53 = -convert(T, 16.31002631330971) + a54 = -convert(T, 1.062004044111401) + C21 = -convert(T, 12) + C31 = -convert(T, 8.791795173947035) + C32 = -convert(T, 2.207865586973518) + C41 = convert(T, 10.81793056857153) + C42 = convert(T, 6.780270611428266) + C43 = convert(T, 19.53485944642410) + C51 = convert(T, 34.19095006749676) + C52 = convert(T, 15.49671153725963) + C53 = convert(T, 54.74760875964130) + C54 = convert(T, 14.16005392148534) + C61 = convert(T, 34.62605830930532) + C62 = convert(T, 15.30084976114473) + C63 = convert(T, 56.99955578662667) + C64 = convert(T, 18.40807009793095) + C65 = -convert(T, 5.714285714285717) + c2 = convert(T2, 3 * gamma) + c3 = convert(T2, 0.21) + c4 = convert(T2, 0.63) + d1 = convert(T, 0.2500000000000000) + d2 = convert(T, -0.5000000000000000) + d3 = convert(T, -0.0235040000000000) + d4 = convert(T, -0.0362000000000000) + + h21 = convert(T, 25.09876703708589) + h22 = convert(T, 11.62013104361867) + h23 = convert(T, 28.49148307714626) + h24 = -convert(T, 5.664021568594133) + h25 = convert(T, 0) + h31 = convert(T, 1.638054557396973) + h32 = -convert(T, 0.7373619806678748) + h33 = convert(T, 8.477918219238990) + h34 = convert(T, 15.99253148779520) + h35 = -convert(T, 1.882352941176471) + + RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, + gamma, c2, c3, c4, d1, d2, d3, d4, + h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) +end + +function Rodas4P2Tableau(T, T2) + gamma = convert(T, 1 // 4) + a21 = convert(T, 3.000000000000000) + a31 = convert(T, 0.906377755268814) + a32 = -convert(T, 0.189707390391685) + a41 = convert(T, 3.758617027739064) + a42 = convert(T, 1.161741776019525) + a43 = -convert(T, 0.849258085312803) + a51 = convert(T, 7.089566927282776) + a52 = convert(T, 4.573591406461604) + a53 = -convert(T, 8.423496976860259) + a54 = -convert(T, 0.959280113459775) + + C21 = convert(T, -12.00000000000000) + C31 = convert(T, -6.354581592719008) + C32 = convert(T, 0.338972550544623) + C41 = convert(T, -8.575016317114033) + C42 = convert(T, -7.606483992117508) + C43 = convert(T, 12.224997650124820) + C51 = convert(T, -5.888975457523102) + C52 = convert(T, -8.157396617841821) + C53 = convert(T, 24.805546872612922) + C54 = convert(T, 12.790401512796979) + C61 = convert(T, -4.408651676063871) + C62 = convert(T, -6.692003137674639) + C63 = convert(T, 24.625568527593117) + C64 = convert(T, 16.627521966636085) + C65 = convert(T, -5.714285714285718) + + c2 = convert(T2, 0.750000000000000) + c3 = convert(T2, 0.321448134013046) + c4 = convert(T2, 0.519745732277726) + d1 = convert(T, 0.250000000000000) + d2 = convert(T, -0.500000000000000) + d3 = convert(T, -0.189532918363016) + d4 = convert(T, 0.085612108792769) + + h21 = convert(T, -5.323528268423303) + h22 = convert(T, -10.042123754867493) + h23 = convert(T, 17.175254928256965) + h24 = convert(T, -5.079931171878093) + h25 = convert(T, -0.016185991706112) + h31 = convert(T, 6.984505741529879) + h32 = convert(T, 6.914061169603662) + h33 = convert(T, -0.849178943070653) + h34 = convert(T, 18.104410789349338) + h35 = convert(T, -3.516963011559032) + + RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, + gamma, c2, c3, c4, d1, d2, d3, d4, + h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) +end + +struct Rodas5Tableau{T, T2} + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + C21::T + C31::T + C32::T + C41::T + C42::T + C43::T + C51::T + C52::T + C53::T + C54::T + C61::T + C62::T + C63::T + C64::T + C65::T + C71::T + C72::T + C73::T + C74::T + C75::T + C76::T + C81::T + C82::T + C83::T + C84::T + C85::T + C86::T + C87::T + gamma::T2 + d1::T + d2::T + d3::T + d4::T + d5::T + c2::T2 + c3::T2 + c4::T2 + c5::T2 + h21::T + h22::T + h23::T + h24::T + h25::T + h26::T + h27::T + h28::T + h31::T + h32::T + h33::T + h34::T + h35::T + h36::T + h37::T + h38::T + h41::T + h42::T + h43::T + h44::T + h45::T + h46::T + h47::T + h48::T +end + +function Rodas5Tableau(T, T2) + gamma = convert(T2, 0.19) + a21 = convert(T, 2.0) + a31 = convert(T, 3.040894194418781) + a32 = convert(T, 1.041747909077569) + a41 = convert(T, 2.576417536461461) + a42 = convert(T, 1.622083060776640) + a43 = convert(T, -0.9089668560264532) + a51 = convert(T, 2.760842080225597) + a52 = convert(T, 1.446624659844071) + a53 = convert(T, -0.3036980084553738) + a54 = convert(T, 0.2877498600325443) + a61 = convert(T, -14.09640773051259) + a62 = convert(T, 6.925207756232704) + a63 = convert(T, -41.47510893210728) + a64 = convert(T, 2.343771018586405) + a65 = convert(T, 24.13215229196062) + C21 = convert(T, -10.31323885133993) + C31 = convert(T, -21.04823117650003) + C32 = convert(T, -7.234992135176716) + C41 = convert(T, 32.22751541853323) + C42 = convert(T, -4.943732386540191) + C43 = convert(T, 19.44922031041879) + C51 = convert(T, -20.69865579590063) + C52 = convert(T, -8.816374604402768) + C53 = convert(T, 1.260436877740897) + C54 = convert(T, -0.7495647613787146) + C61 = convert(T, -46.22004352711257) + C62 = convert(T, -17.49534862857472) + C63 = convert(T, -289.6389582892057) + C64 = convert(T, 93.60855400400906) + C65 = convert(T, 318.3822534212147) + C71 = convert(T, 34.20013733472935) + C72 = convert(T, -14.15535402717690) + C73 = convert(T, 57.82335640988400) + C74 = convert(T, 25.83362985412365) + C75 = convert(T, 1.408950972071624) + C76 = convert(T, -6.551835421242162) + C81 = convert(T, 42.57076742291101) + C82 = convert(T, -13.80770672017997) + C83 = convert(T, 93.98938432427124) + C84 = convert(T, 18.77919633714503) + C85 = convert(T, -31.58359187223370) + C86 = convert(T, -6.685968952921985) + C87 = convert(T, -5.810979938412932) + c2 = convert(T2, 0.38) + c3 = convert(T2, 0.3878509998321533) + c4 = convert(T2, 0.4839718937873840) + c5 = convert(T2, 0.4570477008819580) + d1 = convert(T, gamma) + d2 = convert(T, -0.1823079225333714636) + d3 = convert(T, -0.319231832186874912) + d4 = convert(T, 0.3449828624725343) + d5 = convert(T, -0.377417564392089818) + + h21 = convert(T, 27.354592673333357) + h22 = convert(T, -6.925207756232857) + h23 = convert(T, 26.40037733258859) + h24 = convert(T, 0.5635230501052979) + h25 = convert(T, -4.699151156849391) + h26 = convert(T, -1.6008677469422725) + h27 = convert(T, -1.5306074446748028) + h28 = convert(T, -1.3929872940716344) + + h31 = convert(T, 44.19024239501722) + h32 = convert(T, 1.3677947663381929e-13) + h33 = convert(T, 202.93261852171622) + h34 = convert(T, -35.5669339789154) + h35 = convert(T, -181.91095152160645) + h36 = convert(T, 3.4116351403665033) + h37 = convert(T, 2.5793540257308067) + h38 = convert(T, 2.2435122582734066) + + h41 = convert(T, -44.0988150021747) + h42 = convert(T, -5.755396159656812e-13) + h43 = convert(T, -181.26175034586677) + h44 = convert(T, 56.99302194811676) + h45 = convert(T, 183.21182741427398) + h46 = convert(T, -7.480257918273637) + h47 = convert(T, -5.792426076169686) + h48 = convert(T, -5.32503859794143) + + # println("---Rodas5---") + + #= + a71 = -14.09640773051259 + a72 = 6.925207756232704 + a73 = -41.47510893210728 + a74 = 2.343771018586405 + a75 = 24.13215229196062 + a76 = convert(T,1) + a81 = -14.09640773051259 + a82 = 6.925207756232704 + a83 = -41.47510893210728 + a84 = 2.343771018586405 + a85 = 24.13215229196062 + a86 = convert(T,1) + a87 = convert(T,1) + b1 = -14.09640773051259 + b2 = 6.925207756232704 + b3 = -41.47510893210728 + b4 = 2.343771018586405 + b5 = 24.13215229196062 + b6 = convert(T,1) + b7 = convert(T,1) + b8 = convert(T,1) + =# + + Rodas5Tableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + a61, a62, a63, a64, a65, + C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, + C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, + C81, C82, C83, C84, C85, C86, C87, + gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5, + h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, + h38, h41, h42, h43, h44, h45, h46, h47, h48) +end + +function Rodas5PTableau(T, T2) + gamma = convert(T2, 0.21193756319429014) + + a21 = convert(T, 3.0) + a31 = convert(T, 2.849394379747939) + a32 = convert(T, 0.45842242204463923) + a41 = convert(T, -6.954028509809101) + a42 = convert(T, 2.489845061869568) + a43 = convert(T, -10.358996098473584) + a51 = convert(T, 2.8029986275628964) + a52 = convert(T, 0.5072464736228206) + a53 = convert(T, -0.3988312541770524) + a54 = convert(T, -0.04721187230404641) + a61 = convert(T, -7.502846399306121) + a62 = convert(T, 2.561846144803919) + a63 = convert(T, -11.627539656261098) + a64 = convert(T, -0.18268767659942256) + a65 = convert(T, 0.030198172008377946) + + C21 = convert(T, -14.155112264123755) + C31 = convert(T, -17.97296035885952) + C32 = convert(T, -2.859693295451294) + C41 = convert(T, 147.12150275711716) + C42 = convert(T, -1.41221402718213) + C43 = convert(T, 71.68940251302358) + C51 = convert(T, 165.43517024871676) + C52 = convert(T, -0.4592823456491126) + C53 = convert(T, 42.90938336958603) + C54 = convert(T, -5.961986721573306) + C61 = convert(T, 24.854864614690072) + C62 = convert(T, -3.0009227002832186) + C63 = convert(T, 47.4931110020768) + C64 = convert(T, 5.5814197821558125) + C65 = convert(T, -0.6610691825249471) + C71 = convert(T, 30.91273214028599) + C72 = convert(T, -3.1208243349937974) + C73 = convert(T, 77.79954646070892) + C74 = convert(T, 34.28646028294783) + C75 = convert(T, -19.097331116725623) + C76 = convert(T, -28.087943162872662) + C81 = convert(T, 37.80277123390563) + C82 = convert(T, -3.2571969029072276) + C83 = convert(T, 112.26918849496327) + C84 = convert(T, 66.9347231244047) + C85 = convert(T, -40.06618937091002) + C86 = convert(T, -54.66780262877968) + C87 = convert(T, -9.48861652309627) + + c2 = convert(T2, 0.6358126895828704) + c3 = convert(T2, 0.4095798393397535) + c4 = convert(T2, 0.9769306725060716) + c5 = convert(T2, 0.4288403609558664) + + d1 = convert(T, 0.21193756319429014) + d2 = convert(T, -0.42387512638858027) + d3 = convert(T, -0.3384627126235924) + d4 = convert(T, 1.8046452872882734) + d5 = convert(T, 2.325825639765069) + + h21 = convert(T, 25.948786856663858) + h22 = convert(T, -2.5579724845846235) + h23 = convert(T, 10.433815404888879) + h24 = convert(T, -2.3679251022685204) + h25 = convert(T, 0.524948541321073) + h26 = convert(T, 1.1241088310450404) + h27 = convert(T, 0.4272876194431874) + h28 = convert(T, -0.17202221070155493) + + h31 = convert(T, -9.91568850695171) + h32 = convert(T, -0.9689944594115154) + h33 = convert(T, 3.0438037242978453) + h34 = convert(T, -24.495224566215796) + h35 = convert(T, 20.176138334709044) + h36 = convert(T, 15.98066361424651) + h37 = convert(T, -6.789040303419874) + h38 = convert(T, -6.710236069923372) + + h41 = convert(T, 11.419903575922262) + h42 = convert(T, 2.8879645146136994) + h43 = convert(T, 72.92137995996029) + h44 = convert(T, 80.12511834622643) + h45 = convert(T, -52.072871366152654) + h46 = convert(T, -59.78993625266729) + h47 = convert(T, -0.15582684282751913) + h48 = convert(T, 4.883087185713722) + + Rodas5Tableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + a61, a62, a63, a64, a65, + C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, + C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, + C81, C82, C83, C84, C85, C86, C87, + gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5, + h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, + h38, h41, h42, h43, h44, h45, h46, h47, h48) +end + +@RosenbrockW6S4OS(:tableau) + +#= +# alpha_ij +A = [0 0 0 0 0 0 0 0 + big"0.38" 0 0 0 0 0 0 0 + big"0.1899188971074152" big"0.1979321027247381" 0 0 0 0 0 0 + big"0.1110729281178426" big"0.5456026683145674" big"-0.1727037026450261" 0 0 0 0 0 + big"0.2329444418850307" big"0.025099380960713898" big"0.1443314046300300" big"0.054672473406183418" 0 0 0 0 + big"-0.036201017843430883" big"4.208448872731939" big"-7.549674427720996" big"-0.2076823626400282" big"4.585108935472517" 0 0 0 + big"7.585261698003052" big"-15.57426208319938" big"-8.814406895608121" big"1.534698996826085" big"16.07870828397837" big"0.19" 0 0 + big"0.4646018839086969" big"0" big"-1.720907508837576" big"0.2910480220957973" big"1.821778861539924" big"-0.046521258706842056" big"0.19" 0] +# bi +B = [big"0.464601884",0,big"-1.72090751",big"0.29104802",big"1.82177886",big"-0.02674488",big"-0.01977638",big"0.19"] + +# Beta_ij + +Beta = [big"0.19" 0 0 0 0 0 0 0 + big"0.0076920774666285364" big"0.19" 0 0 0 0 0 0 + big"-0.058129718999580252" big"-0.063251113355141360" big"0.19" 0 0 0 0 0 + big"0.7075715596134048" big"-0.5980299539145789" big"0.5294131505610923" big"0.19" 0 0 0 0 + big"-0.034975026573934865" big"-0.1928476085817357" big"0.089839586125126941" big"0.027613185520411822" big"0.19" 0 0 0 + big"7.585261698003052" big"-15.57426208319938" big"-8.814406895608121" big"1.534698996826085" big"16.07870828397837" big"0.19" 0 0 + big"0.4646018839086969" 0 big"-1.720907508837576" big"0.2910480220957973" big"1.821778861539924" big"-0.046521258706842056" big"0.19" 0 + big"0.4646018839086969" 0 big"-1.720907508837576" big"0.2910480220957973" big"1.821778861539924" big"-0.026744882930135193" big"-0.019776375776706864" big"0.19"] + +Gamma = Beta - A +a = A*Gamma +m = B'*inv(Gamma) # = b_i +C = inv(Diagonal(diag(Gamma))) - inv(Gamma) +c = sum(A,2) +D = Beta*inv(Gamma) +d = sum(Gamma,2) + +# Dense output +D_i = tanspose(D)*k_i +y1(Θ) = y₀*(1-Θ) + Θ*(y₁ + (Θ-1)*(D₂ + D₄ + (Θ + 1)*(D₃ + ΘD₄))) + +# Determining coefficients +gamma = 0.19 +c3 = 0.3878509998321533 == alpha3 +c4 = 0.4839718937873840 == alpha4 +c5 = 0.4570477008819580 == alpha5 +beta3 = 6.8619167645278386e-2 +beta4 = 0.8289547562599182 +beta5 = 7.9630136489868164e-2 +alpha64 = -0.2076823627400282 +=# diff --git a/src/tableaus/sdirk_tableaus.jl b/src/tableaus/sdirk_tableaus.jl new file mode 100644 index 0000000000..ed95cef957 --- /dev/null +++ b/src/tableaus/sdirk_tableaus.jl @@ -0,0 +1,2776 @@ +struct TRBDF2Tableau{T, T2} + γ::T2 + d::T + ω::T + btilde1::T + btilde2::T + btilde3::T + α1::T + α2::T +end + +#= +Tableau: + +c = [0; γ; 1] +A = [0 0 0 + d d 0 + ω ω d] +b = [ω; ω; d] +bhat = [(1-ω)/3; (3ω+1)/3; d/3] + +where γ=2-√2, d=γ/2, and ω=(√2)/4. Hence + +btilde = bhat-b = [(1-4ω)/3; 1/3; -2d/3] = [(1-√2)/3; 1/3; (√2-2)/3] + +Let uᵧ and u be approximations to u(t+γ*dt) and u(t+dt). Then initial guesses of +approximations zᵧ and z to dt*f(t+γ*dt,uᵧ) and dt*f(t+dt,u) according to Shampine: + +zᵧ = zprev + +z = (1.5+√2)*zprev + (2.5+2√2)*zᵧ - (6+4.5√2)*(uᵧ-uprev) = (by def. of uᵧ) + = (1.5+√2)*zprev + (2.5+2√2)*zᵧ - (6+4.5√2)*(d*zᵧ + d*zprev) = + = (-√2)/2*zprev + (1+(√2)/2)*zᵧ +=# +function TRBDF2Tableau(T, T2) + γ = convert(T2, 2 - sqrt(2)) + d = convert(T, 1 - sqrt(2) / 2) + ω = convert(T, sqrt(2) / 4) + btilde1 = convert(T, (1 - sqrt(2)) / 3) + btilde2 = convert(T, 1 // 3) + btilde3 = convert(T, (sqrt(2) - 2) / 3) + α1 = convert(T, -sqrt(2) / 2) + α2 = convert(T, 1 + sqrt(2) / 2) + TRBDF2Tableau(γ, d, ω, btilde1, btilde2, btilde3, α1, α2) +end + +struct ESDIRK4Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + btilde1::T + btilde2::T + btilde3::T + btilde4::T + c3::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 +end + +#= +Derivative of Hermite Polynomial +k[1] + Θ*(-4*dt*k[1] - 2*dt*k[2] - 6*y₀ + Θ*(3*dt*k[1] + 3*dt*k[2] + 6*y₀ - 6*y₁) + 6*y₁)/dt + +Extrapolation for ESDIRK interior step 3 +dt = c2 since interval is [c1,c2] and c1 = 0 +θ = c3/c2 the extrapolation point +z = dt*k + +z₁ + Θ*(-4dt*z₁ - 2dt*z₂ - 6y₀ + Θ*(3dt*z₁ + 3z₂ + 6y₀ - 6y₁ ) + 6y₁)/dt + +Test Expression on TRBDF2: +c2 = 2 - sqrt(2) +c3 = 1 +θ = c3/c2; dt = c2 + +Coefficient on z₁: +(1 + (-4θ + 3θ^2))*z₁ +1 + (-4θ + 3θ^2) - (1.5 + sqrt(2)) # 1.5 + sqrt(2) given by Shampine + +Coefficient on z₂: +(-2θ + 3θ^2)*z₂ +(-2θ + 3θ^2) - (2.5 + 2sqrt(2)) # 2.5 + 2sqrt(2) given by Shampine + +Coefficient on y₁-y₀: +θ*(θ*6(y₀-y₁)+6(y₁-y₀))/dt +θ*(-6θ(y₁-y₀)+6(y₁-y₀))/dt +(y₁-y₀)6θ*(1-θ)/dt + +(6θ*(1-θ)/dt)*(y₁-y₀) + +6θ*(1-θ)/dt - (- (6 + 4.5sqrt(2))) # - (6 + 4.5sqrt(2)) given by Shampine + +# Write only in terms of z primitives +y₀ = uprev +y₁ = uprev + γ*z₁ + γ*z₂ +y₁-y₀ = γ*z₁ + γ*z₂ + +# Full Expression +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/dt)*γ)*z₁ + ((-2θ + 3θ^2) + (6θ*(1-θ)/dt)*γ)*z₂ +=# + +#= +# Kvaerno3 +# Predict z4 from yhat + +yhat = uprev + a31*z1 + a32*z2 + γ*z3 +z₄ = yhat - uprev = a31*z1 + a32*z2 + γ*z3 + +# Note Hermite is too small of an interval for this one!!! +=# + +function Kvaerno3Tableau(T, T2) + γ = convert(T2, 0.4358665215) + a31 = convert(T, 0.490563388419108) + a32 = convert(T, 0.073570090080892) + a41 = convert(T, 0.308809969973036) + a42 = convert(T, 1.490563388254106) + a43 = -convert(T, 1.235239879727145) + # bhat1 = convert(T,0.490563388419108) + # bhat2 = convert(T,0.073570090080892) + # bhat3 = convert(T,0.4358665215) + # bhat4 = convert(T,0.0) + btilde1 = convert(T, 0.181753418446072) # bhat1-a41 + btilde2 = convert(T, -1.416993298173214) # bhat2-a42 + btilde3 = convert(T, 1.671106401227145) # bhat3-a43 + btilde4 = convert(T, -γ) # bhat4-γ + c3 = convert(T2, 1) + c2 = 2γ + θ = c3 / c2 + α31 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) + α32 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) + α41 = convert(T2, 0.0) + α42 = convert(T2, 0.0) + ESDIRK4Tableau(γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, + α32, α41, α42) +end + +struct KenCarp3Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + btilde1::T + btilde2::T + btilde3::T + btilde4::T + c3::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 + ea21::T + ea31::T + ea32::T + ea41::T + ea42::T + ea43::T + eb1::T + eb2::T + eb3::T + eb4::T + ebtilde1::T + ebtilde2::T + ebtilde3::T + ebtilde4::T +end + +#= +# KenCarp3 +# Predict z4 from Hermite z2 and z1 +# Not z3 because c3 < c2 ! + +θ = c3/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) +θ = c4/c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) +=# +function KenCarp3Tableau(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) + γ = convert(T2, 0.435866521508459) + a31 = convert(T, 0.2576482460664272) + a32 = -convert(T, 0.09351476757488625) + a41 = convert(T, 0.18764102434672383) + a42 = -convert(T, 0.595297473576955) + a43 = convert(T, 0.9717899277217721) + # bhat1 = convert(T,2756255671327//12835298489170) + # bhat2 = -convert(T,10771552573575//22201958757719) + # bhat3 = convert(T,9247589265047//10645013368117) + # bhat4 = convert(T,2193209047091//5459859503100) + btilde1 = convert(T, 0.027099261876665316) # bhat1-a41 + btilde2 = convert(T, 0.11013520969201586) # bhat2-a42 + btilde3 = convert(T, -0.10306492520138458) # bhat3-a43 + btilde4 = convert(T, -0.0341695463672966) # bhat4-γ + c3 = convert(T2, 0.6) + c2 = 2γ + θ = c3 / c2 + α31 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) + α32 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) + θ = 1 / c2 + α41 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) + α42 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) + + ea21 = convert(T, 0.871733043016918) + ea31 = convert(T, 0.5275890119763004) + ea32 = convert(T, 0.0724109880236996) + ea41 = convert(T, 0.3990960076760701) + ea42 = -convert(T, 0.4375576546135194) + ea43 = convert(T, 1.0384616469374492) + eb1 = convert(T, 0.18764102434672383) + eb2 = convert(T, -0.595297473576955) + eb3 = convert(T, 0.9717899277217721) + eb4 = convert(T, 0.435866521508459) + ebtilde1 = convert(T, 0.027099261876665316) + ebtilde2 = convert(T, 0.11013520969201586) + ebtilde3 = -convert(T, 0.10306492520138458) + ebtilde4 = -convert(T, 0.0341695463672966) + KenCarp3Tableau( + γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, + α32, α41, α42, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4, + ebtilde1, ebtilde2, ebtilde3, ebtilde4) +end + +function KenCarp3Tableau(T, T2) + γ = convert(T2, 1767732205903 // 4055673282236) + a31 = convert(T, 2746238789719 // 10658868560708) + a32 = -convert(T, 640167445237 // 6845629431997) + a41 = convert(T, 1471266399579 // 7840856788654) + a42 = -convert(T, 4482444167858 // 7529755066697) + a43 = convert(T, 11266239266428 // 11593286722821) + # bhat1 = convert(T,2756255671327//12835298489170) + # bhat2 = -convert(T,10771552573575//22201958757719) + # bhat3 = convert(T,9247589265047//10645013368117) + # bhat4 = convert(T,2193209047091//5459859503100) + btilde1 = convert(T, + BigInt(681815649026867975666107) // + BigInt(25159934323302256049469295)) # bhat1-a41 + btilde2 = convert(T, + BigInt(18411887981491912264464127) // + BigInt(167175311446532472108584143)) # bhat2-a42 + btilde3 = convert(T, + BigInt(-12719313754959329011138489) // + BigInt(123410692144842870217698057)) # bhat3-a43 + btilde4 = convert(T, + BigInt(-47289384293135913063989) // BigInt(1383962894467812063558225)) # bhat4-γ + c3 = convert(T2, 3 // 5) + c2 = 2γ + θ = c3 / c2 + α31 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) + α32 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) + θ = 1 / c2 + α41 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) + α42 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) + + # Explicit Tableau + ea21 = convert(T, 1767732205903 // 2027836641118) + ea31 = convert(T, 5535828885825 // 10492691773637) + ea32 = convert(T, 788022342437 // 10882634858940) + ea41 = convert(T, 6485989280629 // 16251701735622) + ea42 = -convert(T, 4246266847089 // 9704473918619) + ea43 = convert(T, 10755448449292 // 10357097424841) + eb1 = convert(T, 1471266399579 // 7840856788654) + eb2 = convert(T, -4482444167858 // 7529755066697) + eb3 = convert(T, 11266239266428 // 11593286722821) + eb4 = convert(T, 1767732205903 // 4055673282236) + ebtilde1 = convert(T, + BigInt(681815649026867975666107) // + BigInt(25159934323302256049469295)) + ebtilde2 = convert(T, + BigInt(18411887981491912264464127) // + BigInt(167175311446532472108584143)) + ebtilde3 = -convert(T, + BigInt(12719313754959329011138489) // + BigInt(123410692144842870217698057)) + ebtilde4 = -convert(T, + BigInt(47289384293135913063989) // + BigInt(1383962894467812063558225)) + KenCarp3Tableau( + γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, + α32, α41, α42, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4, + ebtilde1, ebtilde2, ebtilde3, ebtilde4) +end + +# Flip them all! + +# ebtilde1 = big(1471266399579)//7840856788654 - big(2756255671327)//12835298489170 +# ebtilde2 = -big(4482444167858)//7529755066697 + big(10771552573575)//22201958757719 +# ebtilde3 = big(11266239266428)//11593286722821 - big(9247589265047)//10645013368117 +# ebtilde4 = big(1767732205903)//4055673282236 - big(2193209047091)//5459859503100 + +struct Cash4Tableau{T, T2} + γ::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + b1hat1::T + b2hat1::T + b3hat1::T + b4hat1::T + b1hat2::T + b2hat2::T + b3hat2::T + b4hat2::T + c2::T2 + c3::T2 + c4::T2 +end + +#= +Extrapolation for Cash interior step 3 +dt = c1-c2 since interval is [c2,c1] and c1 = 0 +c2 < c1, so z₂ is the left +θ = (c3-c1)/dt the extrapolation point +z = dt*k + +z₂ + Θ*(-4dt*z₂ - 2dt*z₁ - 6y₀ + Θ*(3dt*z₂ + 3z₁ + 6y₀ - 6y₁ ) + 6y₁)/dt + +Coefficient on z₁: +(-2θ + 3θ^2) + +Coefficient on z₂: +(1 + (-4θ + 3θ^2)) + +Coefficient on y₁-y₀: +(6θ*(1-θ)/dt) + +# Write only in terms of z primitives +y₁ = uprev + a21*z₁ + γ*z₂ +y₀ = uprev + γ*z₁ +y₁-y₀ = (a21-γ)*z₁ + γ*z₂ + +θ = 1.1 +Full z₁ coefficient: (-2θ + 3θ^2) + (6θ*(1-θ)/dt)*(a21-γ) +Full z₂ coefficient: (1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/dt)*γ + +f(θ)= (-2θ + 3θ^2) + (6θ*(1-θ)/dt)*(a21-γ) +g(θ) = (1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/dt)*γ +t = linspace(0,1.5,100) +y = f.(t) +z = g.(t) +plot(t,y) +plot!(t,z) + +The extrapolation is really bad that far +Hairer's extrapolation is no better. +Using constant extrapolations +=# + +function Cash4Tableau(T, T2) + γ = convert(T2, 0.435866521508) + a21 = convert(T, -1.13586652150) + a31 = convert(T, 1.08543330679) + a32 = -convert(T, 0.721299828287) + a41 = convert(T, 0.416349501547) + a42 = convert(T, 0.190984004184) + a43 = convert(T, -0.118643265417) + a51 = convert(T, 0.896869652944) + a52 = convert(T, 0.0182725272734) + a53 = -convert(T, 0.0845900310706) + a54 = -convert(T, 0.266418670647) + b1hat1 = convert(T, 1.05646216107052) + b2hat1 = -convert(T, 0.0564621610705236) + b3hat1 = convert(T, 0) + b4hat1 = convert(T, 0) + b1hat2 = convert(T, 0.776691932910) + b2hat2 = convert(T, 0.0297472791484) + b3hat2 = -convert(T, 0.0267440239074) + b4hat2 = convert(T, 0.220304811849) + c2 = -convert(T2, 0.7) + c3 = convert(T2, 0.8) + c4 = convert(T2, 0.924556761814) + Cash4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + b1hat1, b2hat1, b3hat1, b4hat1, b1hat2, b2hat2, b3hat2, b4hat2, c2, c3, c4) +end + +struct SFSDIRK4Tableau{T, T2} + γ::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + c2::T2 + c3::T2 + c4::T2 +end + +function SFSDIRK4Tableau(T, T2) + γ = convert(T2, 0.097961082941) + a21 = convert(T, 0.262318069183) + a31 = convert(T, 0.230169419019) + a32 = convert(T, 0.294466719347) + a41 = convert(T, 0.210562684389) + a42 = convert(T, 0.269382888280) + a43 = convert(T, 0.307008634881) + a51 = convert(T, 0.222119403264) + a52 = convert(T, 0.282060762166) + a53 = convert(T, 0.236881213175) + a54 = convert(T, 0.258938621395) + c2 = convert(T2, 0.360279152124) + c3 = convert(T2, 0.622597221298) + c4 = convert(T2, 0.884915290491) + SFSDIRK4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4) +end + +struct SFSDIRK5Tableau{T, T2} + γ::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + c2::T2 + c3::T2 + c4::T2 + c5::T2 +end + +function SFSDIRK5Tableau(T, T2) + γ = convert(T2, 0.078752939968) + a21 = convert(T, 0.222465723027) + a31 = convert(T, 0.203192361700) + a32 = convert(T, 0.230847263068) + a41 = convert(T, 0.188022704389) + a42 = convert(T, 0.191735630027) + a43 = convert(T, 0.209922288451) + a51 = convert(T, 0.188025114093) + a52 = convert(T, 0.191739898281) + a53 = convert(T, 0.209907601860) + a54 = convert(T, 0.252726086329) + a61 = convert(T, 0.192143833571) + a62 = convert(T, 0.200935182974) + a63 = convert(T, 0.205799262036) + a64 = convert(T, 0.200553844640) + a65 = convert(T, 0.200567876778) + c2 = convert(T2, 0.301218662995) + c3 = convert(T2, 0.512792564736) + c4 = convert(T2, 0.668433562835) + c5 = convert(T2, 0.921151640531) + SFSDIRK5Tableau( + γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, c2, c3, c4, c5) +end + +struct SFSDIRK6Tableau{T, T2} + γ::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 +end + +function SFSDIRK6Tableau(T, T2) + γ = convert(T2, 0.067410767219) + a21 = convert(T, 0.194216850802) + a31 = convert(T, 0.194216850802) + a32 = convert(T, 0.199861501713) + a41 = convert(T, 0.162188551749) + a42 = convert(T, 0.166902343330) + a43 = convert(T, 0.145120313717) + a51 = convert(T, 0.165176818500) + a52 = convert(T, 0.169977460026) + a53 = convert(T, 0.150227711763) + a54 = convert(T, 0.181214258555) + a61 = convert(T, 0.165176818500) + a62 = convert(T, 0.169977460026) + a63 = convert(T, 0.150227711763) + a64 = convert(T, 0.181214258555) + a65 = convert(T, 0.199861501713) + a71 = convert(T, 0.168954170460) + a72 = convert(T, 0.173864595628) + a73 = convert(T, 0.156683775305) + a74 = convert(T, 0.157643002581) + a75 = convert(T, 0.173864725004) + a76 = convert(T, 0.168989731022) + c2 = convert(T2, 0.261627618021) + c3 = convert(T2, 0.461489119734) + c4 = convert(T2, 0.541621976015) + c5 = convert(T2, 0.734007016063) + c6 = convert(T2, 0.933868517776) + SFSDIRK6Tableau( + γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, a71, a72, a73, a74, a75, a76, c2, c3, c4, c5, c6) +end + +struct SFSDIRK7Tableau{T, T2} + γ::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + a81::T + a82::T + a83::T + a84::T + a85::T + a86::T + a87::T + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 +end + +function SFSDIRK7Tableau(T, T2) + γ = convert(T2, 0.056879041592) + a21 = convert(T, 0.172205581756) + a31 = convert(T, 0.135485903539) + a32 = convert(T, 0.135485903539) + a41 = convert(T, 0.133962606568) + a42 = convert(T, 0.133962606568) + a43 = convert(T, 0.170269437596) + a51 = convert(T, 0.133962606568) + a52 = convert(T, 0.133962606568) + a53 = convert(T, 0.170269437596) + a54 = convert(T, 0.172205581756) + a61 = convert(T, 0.138004377067) + a62 = convert(T, 0.133084723451) + a63 = convert(T, 0.152274237527) + a64 = convert(T, 0.154005757170) + a65 = convert(T, 0.154005757170) + a71 = convert(T, 0.139433665640) + a72 = convert(T, 0.134719607258) + a73 = convert(T, 0.145910607076) + a74 = convert(T, 0.147569765489) + a75 = convert(T, 0.147569765489) + a76 = convert(T, 0.165009008641) + a81 = convert(T, 0.138370770799) + a82 = convert(T, 0.134572540279) + a83 = convert(T, 0.150642940425) + a84 = convert(T, 0.152355910489) + a85 = convert(T, 0.152355910489) + a86 = convert(T, 0.132951737506) + a87 = convert(T, 0.138750190012) + c2 = convert(T2, 0.229084623348) + c3 = convert(T2, 0.32785084867) + c4 = convert(T2, 0.495073692324) + c5 = convert(T2, 0.66727927408) + c6 = convert(T2, 0.788253893977) + c7 = convert(T2, 0.937091461185) + SFSDIRK7Tableau( + γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, + c2, c3, c4, c5, c6, c7) +end + +struct SFSDIRK8Tableau{T, T2} + γ::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + a81::T + a82::T + a83::T + a84::T + a85::T + a86::T + a87::T + a91::T + a92::T + a93::T + a94::T + a95::T + a96::T + a97::T + a98::T + c2::T2 + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + c8::T2 +end + +function SFSDIRK8Tableau(T, T2) + γ = convert(T2, 0.050353353407) + a21 = convert(T, 0.147724666662) + a31 = convert(T, 0.114455029802) + a32 = convert(T, 0.114455029802) + a41 = convert(T, 0.114147680771) + a42 = convert(T, 0.114147680771) + a43 = convert(T, 0.147327977820) + a51 = convert(T, 0.114163314686) + a52 = convert(T, 0.114163314686) + a53 = convert(T, 0.147259379853) + a54 = convert(T, 0.147655883990) + a61 = convert(T, 0.114163314686) + a62 = convert(T, 0.114163314686) + a63 = convert(T, 0.147259379853) + a64 = convert(T, 0.147655883990) + a65 = convert(T, 0.147724666662) + a71 = convert(T, 0.118472990244) + a72 = convert(T, 0.118472990244) + a73 = convert(T, 0.128349529304) + a74 = convert(T, 0.128695117609) + a75 = convert(T, 0.128755067770) + a76 = convert(T, 0.128755067770) + a81 = convert(T, 0.118472990244) + a82 = convert(T, 0.118472990244) + a83 = convert(T, 0.128349529304) + a84 = convert(T, 0.128695117609) + a85 = convert(T, 0.128755067770) + a86 = convert(T, 0.128755067770) + a87 = convert(T, 0.147724666662) + a91 = convert(T, 0.117592883046) + a92 = convert(T, 0.117592883046) + a93 = convert(T, 0.132211234288) + a94 = convert(T, 0.132567220450) + a95 = convert(T, 0.132628974356) + a96 = convert(T, 0.132293123539) + a97 = convert(T, 0.117556840638) + a98 = convert(T, 0.117556840638) + c2 = convert(T2, 0.198078020069) + c3 = convert(T2, 0.279263413011) + c4 = convert(T2, 0.425976692769) + c5 = convert(T2, 0.573595246622) + c6 = convert(T2, 0.721319913284) + c7 = convert(T2, 0.801854116348) + c8 = convert(T2, 0.94957878301) + SFSDIRK8Tableau( + γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, + a91, a92, a93, a94, a95, a96, a97, a98, c2, c3, c4, c5, c6, c7, c8) +end + +struct Hairer4Tableau{T, T2} + γ::T2 + a21::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + bhat1::T + bhat2::T + bhat3::T + bhat4::T + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + c2::T2 + c3::T2 + c4::T2 + r11::T + r12::T + r13::T + r14::T + r21::T + r22::T + r23::T + r24::T + r31::T + r32::T + r33::T + r34::T + r41::T + r42::T + r43::T + r44::T + r51::T + r52::T + r53::T + r54::T + α21::T2 + α31::T2 + α32::T2 + α41::T2 + α43::T2 +end + +function Hairer4Tableau(T, T2) + γ = convert(T2, 1 // 4) + c2 = convert(T2, 3 // 4) + c3 = convert(T2, 11 // 20) + c4 = convert(T2, 1 // 2) + + #= + α21 = convert(T,2) + α31 = convert(T,42//25) + α32 = -convert(T,4//25) + α41 = convert(T,89//68) + α42 = -convert(T,25//136) + α43 = convert(T,15//136) + α51 = -convert(T,37//12) + α52 = -convert(T,103//24) + α53 = convert(T,275//8) + α54 = -convert(T,85//3) + + alpha = -inv(A)*γ + + α = [-1 0 0 0 0 + α21 -1 0 0 0 + α31 α32 -1 0 0 + α41 α42 α43 -1 0 + α51 α52 α53 α54 -1] + A α = -γ + A = -γ*inv(α) + + Now zⱼ = fⱼ + ∑α_ⱼᵢ zᵢ + =# + + a11 = convert(T, 1 // 4) + a21 = convert(T, 1 // 2) + a22 = convert(T, 1 // 4) + a31 = convert(T, 17 // 50) + a32 = convert(T, -1 // 25) + a33 = convert(T, 1 // 4) + a41 = convert(T, 371 // 1360) + a42 = convert(T, -137 // 2720) + a43 = convert(T, 15 // 544) + a44 = convert(T, 1 // 4) + a51 = convert(T, 25 // 24) + a52 = convert(T, -49 // 48) + a53 = convert(T, 125 // 16) + a54 = convert(T, -85 // 12) + + #= + e1 = -convert(T,23//6) + e2 = -convert(T,17//12) + e3 = convert(T,125//4) + e4 = -convert(T,85//3) + E = [e1 e2 e3 e4 0] + + bhat = [59//48,-17//96,225//32,-85//12,0] + + α = [-1 0 0 0 0 + α21 -1 0 0 0 + α31 α32 -1 0 0 + α41 α42 α43 -1 0 + e1 e2 e3 e4 -1] + + A = [γ 0 0 0 0 + a21 γ 0 0 0 + a31 a32 γ 0 0 + a41 a42 a43 γ 0 + a51 a52 a53 a54 γ] + + E = bhat'*inv(A) + bhat = E*A + =# + + bhat1 = convert(T, 59 // 48) + bhat2 = convert(T, -17 // 96) + bhat3 = convert(T, 225 // 32) + bhat4 = convert(T, -85 // 12) + + btilde1 = convert(T, 3 // 16) # bhat1-a51 + btilde2 = convert(T, 27 // 32) # bhat2-a52 + btilde3 = convert(T, -25 // 32) # bhat3-a53 + btilde4 = convert(T, 0) # bhat4-a54 + btilde5 = -γ + + #= + d11 = convert(T,61//27) + d12 = convert(T,-185//54) + d13 = convert(T,2525//18) + d14 = convert(T,-3740//27) + d15 = convert(T,-44//9) + d21 = convert(T,2315//81) + d22 = convert(T,1049//162) + d23 = convert(T,-27725//54) + d24 = convert(T,40460//81) + d25 = convert(T,557//27) + d31 = convert(T,-6178//81) + d32 = convert(T,-1607//81) + d33 = convert(T,20075//27) + d34 = convert(T,-56440//81) + d35 = convert(T,-718//27) + d41 = convert(T,3680//81) + d42 = convert(T,1360//81) + d43 = convert(T,-10000//27) + d44 = convert(T,27200//81) + d45 = convert(T,320//27) + + D = [d11 d12 d13 d14 d15 + d21 d22 d23 d24 d25 + d31 d32 d33 d34 d35 + d41 d42 d43 d44 d45] + R = (D*A)' + =# + + r11 = convert(T, 11 // 3) + r12 = convert(T, -463 // 72) + r13 = convert(T, 217 // 36) + r14 = convert(T, -20 // 9) + r21 = convert(T, 11 // 2) + r22 = convert(T, -385 // 16) + r23 = convert(T, 661 // 24) + r24 = convert(T, -10 // 1) + r31 = convert(T, -125 // 18) + r32 = convert(T, 20125 // 432) + r33 = convert(T, -8875 // 216) + r34 = convert(T, 250 // 27) + r41 = convert(T, 0) + r42 = convert(T, -85 // 4) + r43 = convert(T, 85 // 6) + r44 = convert(T, 0 // 1) + r51 = convert(T, -11 // 9) + r52 = convert(T, 557 // 108) + r53 = convert(T, -359 // 54) + r54 = convert(T, 80 // 27) + + # c2/γ + α21 = convert(T2, 3) + #= + # Prediction alphas from Hairer + # Predict z3 from z1 and z2 + A = [c1 c2 + γ*c1 a21*c1+γ*c2] + b = [c3,a31*c1+a32*c2+γ*c3] + A\b + =# + α31 = convert(T2, 88 // 100) + α32 = convert(T2, 44 // 100) + #= + # Predict z4 from z1 and z3 + A = [c1 c3 + γ*c1 a31*c1+a32*c2+γ*c3] + b = [c4,a41*c1+a42*c2+a43*c3+γ*c4] + A\b + =# + α41 = convert(T2, 3 // 17) + α43 = convert(T2, 155 // 187) + + Hairer4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, + btilde4, btilde5, c2, c3, c4, r11, r12, r13, r14, + r21, r22, r23, r24, r31, r32, r33, r34, r41, r42, r43, r44, r51, + r52, r53, r54, α21, α31, α32, α41, α43) +end + +function Hairer42Tableau(T, T2) + γ = convert(T, 4 // 15) + c2 = convert(T2, 23 // 30) + c3 = convert(T2, 17 // 30) + c4 = convert(T2, 2881 // 28965) + γ + #= + α21 = convert(T,15//8) + α31 = convert(T,1577061//922880) + α32 = -convert(T,23427//115360) + α41 = convert(T,647163682356923881//2414496535205978880) + α42 = -convert(T,593512117011179//3245291041943520) + α43 = convert(T,559907973726451//1886325418129671) + α51 = convert(T,724545451//796538880) + α52 = -convert(T,830832077//267298560) + α53 = convert(T,30957577//2509272) + α54 = -convert(T,69863904375173//6212571137048) + + α = [-1 0 0 0 0 + α21 -1 0 0 0 + α31 α32 -1 0 0 + α41 α42 α43 -1 0 + α51 α52 α53 α54 -1] + A = -γ*inv(α) + =# + a21 = convert(T, 1 // 2) + a31 = convert(T, 51069 // 144200) + a32 = convert(T, -7809 // 144200) + a41 = convert(T, 12047244770625658 // 141474406359725325) + a42 = convert(T, -3057890203562191 // 47158135453241775) + a43 = convert(T, 2239631894905804 // 28294881271945065) + a51 = convert(T, 181513 // 86430) + a52 = convert(T, -89074 // 116015) + a53 = convert(T, 83636 // 34851) + a54 = convert(T, -69863904375173 // 23297141763930) + + #= + + A = [γ 0 0 0 0 + a21 γ 0 0 0 + a31 a32 γ 0 0 + a41 a42 a43 γ 0 + a51 a52 a53 a54 γ] + + A = convert(Array{Rational{BigInt}},A) + + e1 = convert(T,7752107607//11393456128) + e2 = -convert(T,17881415427//11470078208) + e3 = convert(T,2433277665//179459416) + e4 = -convert(T,96203066666797//6212571137048) + E = [e1 e2 e3 e4 0] + + bhat = E*A + =# + + bhat1 = convert(T, 33665407 // 11668050) + bhat2 = convert(T, -2284766 // 15662025) + bhat3 = convert(T, 11244716 // 4704885) + bhat4 = convert(T, -96203066666797 // 23297141763930) + + btilde1 = convert(T, 4580576 // 5834025) # bhat1-a51 + btilde2 = convert(T, 9740224 // 15662025) # bhat2-a52 + btilde3 = convert(T, -46144 // 4704885) # bhat3-a53 + btilde4 = convert(T, -13169581145812 // 11648570881965) # bhat4-a54 + btilde5 = -γ + + #= + d11 = convert(T,24.74416644927758) + d12 = -convert(T,4.325375951824688) + d13 = convert(T,41.39683763286316) + d14 = convert(T,-61.04144619901784) + d15 = convert(T,-3.391332232917013) + d21 = convert(T,-51.98245719616925) + d22 = convert(T,10.52501981094525) + d23 = convert(T,-154.2067922191855) + d24 = convert(T,214.3082125319825) + d25 = convert(T,14.71166018088679) + d31 = convert(T,33.14347947522142) + d32 = convert(T,-19.72986789558523) + d33 = convert(T,230.4878502285804) + d34 = convert(T,-287.6629744338197) + d35 = convert(T,-18.99932366302254) + d41 = convert(T,-5.905188728329743) + d42 = convert(T,13.53022403646467) + d43 = convert(T,-117.6778956422581) + d44 = convert(T,134.3962081008550) + d45 = convert(T,8.678995715052762) + =# + + r11 = convert(T, 6.776439256624082) + r12 = convert(T, -14.066831911883533) + r13 = convert(T, 16.204808856162565) + r14 = convert(T, -6.8143005003361985) + r21 = convert(T, 3.166691382949011) + r22 = convert(T, -14.034196189427504) + r23 = convert(T, 15.497198116229603) + r24 = convert(T, -5.3974733381957005) + r31 = convert(T, -1.9310469085972866) + r32 = convert(T, 11.146663701107887) + r33 = convert(T, -6.9009212321038405) + r34 = convert(T, 0.085120800673252) + r41 = convert(T, -6.107728468864632) + r42 = convert(T, 13.031255018633459) + r43 = convert(T, -19.734599430149146) + r44 = convert(T, 9.812254180511282) + r51 = convert(T, -0.9043552621112034) + r52 = convert(T, 3.9231093815698106) + r53 = convert(T, -5.066486310139344) + r54 = convert(T, 2.3143988573474035) + + # c2/γ + α21 = convert(T, 23 // 8) + α31 = convert(T, 0.9838473040915402) + α32 = convert(T, 0.3969226768377252) + α41 = convert(T, 0.6563374010466914) + α43 = convert(T, 0.3372498196189311) + + Hairer4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, + bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, btilde4, btilde5, + c2, c3, c4, r11, r12, r13, r14, + r21, r22, r23, r24, r31, r32, r33, r34, r41, r42, r43, r44, r51, + r52, r53, r54, α21, α31, α32, α41, α43) +end + +struct Kvaerno4Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + c3::T2 + c4::T2 + α21::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 +end + +#= +# Kvaerno4 +# Predict z3 from Hermite z2 and z1 + +c2 = 2γ +θ = c3/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z4 from Hermite z2 and z1 + +θ = c4/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) +=# + +function Kvaerno4Tableau(T, T2) + γ = convert(T2, 0.4358665215) + a31 = convert(T, 0.140737774731968) + a32 = convert(T, -0.108365551378832) + a41 = convert(T, 0.102399400616089) + a42 = convert(T, -0.376878452267324) + a43 = convert(T, 0.838612530151233) + a51 = convert(T, 0.157024897860995) + a52 = convert(T, 0.117330441357768) + a53 = convert(T, 0.61667803039168) + a54 = convert(T, -0.326899891110444) + btilde1 = convert(T, -0.054625497244906) # a41 - a51 + btilde2 = convert(T, -0.494208893625092) # a42 - a52 + btilde3 = convert(T, 0.221934499759553) # a43 - a53 + btilde4 = convert(T, 0.762766412610444) # γ - a54 + btilde5 = -γ + c3 = convert(T2, 0.468238744853136) + c4 = convert(T2, 1) + α21 = convert(T2, 2) # c2/γ + α31 = convert(T2, 0.462864521870446) + α32 = convert(T2, 0.537135478129554) + α41 = convert(T2, -0.14714018016178376) + α42 = convert(T2, 1.1471401801617838) + Kvaerno4Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, + btilde1, btilde2, btilde3, btilde4, btilde5, + c3, c4, α21, α31, α32, α41, α42) +end + +struct KenCarp4Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a63::T + a64::T + a65::T + btilde1::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + c3::T2 + c4::T2 + c5::T2 + α21::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 + α51::T2 + α52::T2 + α53::T2 + α54::T2 + α61::T2 + α62::T2 + α63::T2 + α64::T2 + α65::T2 + ea21::T + ea31::T + ea32::T + ea41::T + ea42::T + ea43::T + ea51::T + ea52::T + ea53::T + ea54::T + ea61::T + ea62::T + ea63::T + ea64::T + ea65::T + eb1::T + eb3::T + eb4::T + eb5::T + eb6::T + ebtilde1::T + ebtilde3::T + ebtilde4::T + ebtilde5::T + ebtilde6::T +end + +struct CFNLIRK3Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + c2::T2 + c3::T2 + ea21::T + ea31::T + ea32::T + ea41::T + ea42::T + ea43::T + eb1::T + eb2::T + eb3::T + eb4::T +end + +function CFNLIRK3Tableau(T, T2) + #Implicit Tableau + γ = convert(T2, 0.43586652150846) + a31 = convert(T, 0.0) + a32 = convert(T, (1 - γ) / 2) + a41 = convert(T, 0.0) + a42 = convert(T, 1.20849664917601276) + a43 = convert(T, -0.64436317068447276) + c3 = (1 + γ) / 2 + c2 = γ + + # Explicit Tableau + ea21 = convert(T, γ) + ea31 = convert(T, (1.7 + γ) / 2) + ea32 = convert(T, -0.35) + ea41 = convert(T, 0.0) + ea42 = convert(T, 1.9891757246798590) + ea43 = convert(T, -0.9891757246798590) + eb1 = convert(T, 0.0) + eb2 = convert(T, 1.20849664917601276) + eb3 = convert(T, -0.64436317068447276) + eb4 = convert(T, γ) + CFNLIRK3Tableau(γ, a31, a32, a41, a42, a43, c2, c3, ea21, ea31, ea32, ea41, ea42, ea43, + eb1, eb2, eb3, eb4) +end + +#= +# KenCarp4 +# Predict z3 from Hermite z2 and z1 + +c2 = 2γ +θ = c3/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z4 from Hermite z2 and z1 +θ = c4/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z5 from Hermite z2 and z1 +θ = c5/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z5 from z1 and z4 + +θ = c5/c4 +dt = c4 + +y₀ = uprev +y₁ = uprev + a41*z₁ + a42*z₂ + a43*z₃ + γ*z₄ +y₁-y₀ = a41*z₁ + a42*z₂ + a43*z₃ + γ*z₄ + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₅ ++ (6θ*(1-θ)/dt)*(a52*z₂ + a53*z₃ + a54*z₄) + +(1 + (-4θ + 3θ^2) + a41*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a42 +(6θ*(1-θ)/dt)*a43 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +# Predict last stage from z1 and z5 + +θ = 1/c5 +dt = c5 + +y₀ = uprev +y₁ = uprev + a51*z₁ + a52*z₂ + a53*z₃ + a54*z₄ + γ*z₅ +y₁-y₀ = a51*z₁ + a52*z₂ + a53*z₃ + a54*z₄ + γ*z₅ + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₅ ++ (6θ*(1-θ)/dt)*(a52*z₂ + a53*z₃ + a54*z₄) + +(1 + (-4θ + 3θ^2) + a51*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a52 +(6θ*(1-θ)/dt)*a53 +(6θ*(1-θ)/dt)*a54 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +=# +function KenCarp4Tableau(T, T2) + γ = convert(T2, 1 // 4) + a31 = convert(T, 8611 // 62500) + a32 = -convert(T, 1743 // 31250) + a41 = convert(T, 5012029 // 34652500) + a42 = -convert(T, 654441 // 2922500) + a43 = convert(T, 174375 // 388108) + a51 = convert(T, 15267082809 // 155376265600) + a52 = -convert(T, 71443401 // 120774400) + a53 = convert(T, 730878875 // 902184768) + a54 = convert(T, 2285395 // 8070912) + a61 = convert(T, 82889 // 524892) + a63 = convert(T, 15625 // 83664) + a64 = convert(T, 69875 // 102672) + a65 = -convert(T, 2260 // 8211) + # bhat1 = convert(T,4586570599//29645900160) + # bhat3 = convert(T,178811875//945068544) + # bhat4 = convert(T,814220225//1159782912) + # bhat5 = -convert(T,3700637//11593932) + # bhat6 = convert(T,61727//225920) + btilde1 = convert(T, -31666707 // 9881966720) # bhat1-a61 + btilde3 = convert(T, 256875 // 105007616) # bhat3-a63 + btilde4 = convert(T, 2768025 // 128864768) # bhat4-a64 + btilde5 = convert(T, -169839 // 3864644) # bhat5-a65 + btilde6 = convert(T, 5247 // 225920) # bhat6-γ + c3 = convert(T2, 83 // 250) + c4 = convert(T2, 31 // 50) + c5 = convert(T2, 17 // 20) + α21 = convert(T2, 2) # c2/γ + α31 = convert(T2, 42 // 125) + α32 = convert(T2, 83 // 125) + α41 = convert(T2, -6 // 25) + α42 = convert(T2, 31 // 25) + α51 = convert(T2, 914470432 // 2064665255) + α52 = convert(T2, 798813 // 724780) + α53 = convert(T2, -824765625 // 372971788) + α54 = convert(T2, 49640 // 29791) + α61 = convert(T2, 288521442795 // 954204491116) + α62 = convert(T2, 2224881 // 2566456) + α63 = convert(T2, -1074821875 // 905317354) + α64 = convert(T2, -3360875 // 8098936) + α65 = convert(T2, 7040 // 4913) + + ea21 = convert(T, 1 // 2) + ea31 = convert(T, 13861 // 62500) + ea32 = convert(T, 6889 // 62500) + ea41 = -convert(T, 116923316275 // 2393684061468) + ea42 = -convert(T, 2731218467317 // 15368042101831) + ea43 = convert(T, 9408046702089 // 11113171139209) + ea51 = -convert(T, 451086348788 // 2902428689909) + ea52 = -convert(T, 2682348792572 // 7519795681897) + ea53 = convert(T, 12662868775082 // 11960479115383) + ea54 = convert(T, 3355817975965 // 11060851509271) + ea61 = convert(T, 647845179188 // 3216320057751) + ea62 = convert(T, 73281519250 // 8382639484533) + ea63 = convert(T, 552539513391 // 3454668386233) + ea64 = convert(T, 3354512671639 // 8306763924573) + ea65 = convert(T, 4040 // 17871) + + eb1 = convert(T, 82889 // 524892) + eb3 = convert(T, 15625 // 83664) + eb4 = convert(T, 69875 // 102672) + eb5 = -convert(T, 2260 // 8211) + eb6 = convert(T, 1 // 4) + + ebtilde1 = -convert(T, 31666707 // 9881966720) + ebtilde3 = convert(T, 256875 // 105007616) + ebtilde4 = convert(T, 2768025 // 128864768) + ebtilde5 = -convert(T, 169839 // 3864644) + ebtilde6 = convert(T, 5247 // 225920) + + KenCarp4Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, + btilde1, btilde3, btilde4, btilde5, btilde6, + c3, c4, c5, + α21, α31, α32, α41, α42, α51, α52, α53, α54, α61, α62, α63, α64, α65, + ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, + ea63, ea64, ea65, eb1, eb3, eb4, eb5, eb6, ebtilde1, ebtilde3, ebtilde4, + ebtilde5, ebtilde6) +end + +# Flip them all! + +# ebtilde1 = 82889//524892 - 4586570599//29645900160 +# ebtilde3 = 15625//83664 - 178811875//945068544 +# ebtilde4 = 69875//102672 - 814220225//1159782912 +# ebtilde5 = -2260//8211 + 3700637//11593932 +# ebtilde6 = 1//4 - 61727//225920 + +struct Kvaerno5Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a63::T + a64::T + a65::T + a71::T + a73::T + a74::T + a75::T + a76::T + btilde1::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 + α43::T2 + α51::T2 + α52::T2 + α53::T2 + α61::T2 + α62::T2 + α63::T2 +end + +#= +# Kvaerno5 +# Predict z3 from Hermite z2 and z1 + +c2 = 2γ +θ = c3/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict others from z1 and z3 since it covers [0,1.23] + +dt = c3 since interval is [c1,c3] and c1 = 0 +θ = c4/c3, c5/c3, c6/c3, c7/c3 +z = dt*k + +z₁ + Θ*(-4dt*z₁ - 2dt*z₃ - 6y₀ + Θ*(3dt*z₁ + 3z₃ + 6y₀ - 6y₁ ) + 6y₁)/dt + +(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) + +y₀ = uprev +y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ +y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ + (6θ*(1-θ)/dt)*a32*z₂ + +dt = c3 +θ = c4/c3 +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a32 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +θ = c5/c3 +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a32 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +θ = c6/c3 +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a32 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) +=# + +function Kvaerno5Tableau(T, T2) + γ = convert(T2, 0.26) + a31 = convert(T, 0.13) + a32 = convert(T, 0.84033320996790809) + a41 = convert(T, 0.22371961478320505) + a42 = convert(T, 0.47675532319799699) + a43 = -convert(T, 0.06470895363112615) + a51 = convert(T, 0.16648564323248321) + a52 = convert(T, 0.10450018841591720) + a53 = convert(T, 0.03631482272098715) + a54 = -convert(T, 0.13090704451073998) + a61 = convert(T, 0.13855640231268224) + a63 = -convert(T, 0.04245337201752043) + a64 = convert(T, 0.02446657898003141) + a65 = convert(T, 0.61943039072480676) + a71 = convert(T, 0.13659751177640291) + a73 = -convert(T, 0.05496908796538376) + a74 = -convert(T, 0.04118626728321046) + a75 = convert(T, 0.62993304899016403) + a76 = convert(T, 0.06962479448202728) + btilde1 = convert(T, 0.00195889053627933) # a61-a71 + btilde3 = convert(T, 0.01251571594786333) # a63-a73 + btilde4 = convert(T, 0.06565284626324187) # a64-a74 + btilde5 = -convert(T, 0.01050265826535727) # a65-a75 + btilde6 = convert(T, 0.19037520551797272) # γ-a76 + btilde7 = -γ + α21 = convert(T, 2) # c2/γ + α31 = convert(T2, -1.366025403784441) + α32 = convert(T2, 2.3660254037844357) + α41 = convert(T2, -0.19650552613122207) + α42 = convert(T2, 0.8113579546496623) + α43 = convert(T2, 0.38514757148155954) + α51 = convert(T2, 0.10375304369958693) + α52 = convert(T2, 0.937994698066431) + α53 = convert(T2, -0.04174774176601781) + α61 = convert(T2, -0.17281112873898072) + α62 = convert(T2, 0.6235784481025847) + α63 = convert(T2, 0.5492326806363959) + c3 = convert(T, 1.230333209967908) + c4 = convert(T, 0.895765984350076) + c5 = convert(T, 0.436393609858648) + c6 = convert(T, 1) + Kvaerno5Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, + a61, a63, a64, a65, a71, a73, a74, a75, a76, + btilde1, btilde3, btilde4, btilde5, btilde6, btilde7, + c3, c4, c5, c6, α31, α32, α41, α42, α43, α51, α52, α53, + α61, α62, α63) +end + +struct KenCarp5Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a43::T + a51::T + a53::T + a54::T + a61::T + a63::T + a64::T + a65::T + a71::T + a73::T + a74::T + a75::T + a76::T + a81::T + a84::T + a85::T + a86::T + a87::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 + α51::T2 + α52::T2 + α61::T2 + α62::T2 + α71::T2 + α72::T2 + α73::T2 + α74::T2 + α75::T2 + α81::T2 + α82::T2 + α83::T2 + α84::T2 + α85::T2 + btilde1::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + btilde8::T + ea21::T + ea31::T + ea32::T + ea41::T + ea43::T + ea51::T + ea53::T + ea54::T + ea61::T + ea63::T + ea64::T + ea65::T + ea71::T + ea73::T + ea74::T + ea75::T + ea76::T + ea81::T + ea83::T + ea84::T + ea85::T + ea86::T + ea87::T + eb1::T + eb4::T + eb5::T + eb6::T + eb7::T + eb8::T + ebtilde1::T + ebtilde4::T + ebtilde5::T + ebtilde6::T + ebtilde7::T + ebtilde8::T +end + +#= +# KenCarp5 +# Predict z3 from Hermite z2 and z1 + +c2 = 2γ +θ = c3/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z4 from z2 and z1 +θ = c4/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z5 from z2 and z1 +θ = c5/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z6 from z2 and z1 +θ = c6/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z7 from z5 and z1 +θ = c7/c5 +dt = c5 + +(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) +y₁-y₀ = a51*z₁ + a52*z₂ + a53*z₃ + a54*z₄ + γ*z₅ + +(1 + (-4θ + 3θ^2) + a51*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a52 +(6θ*(1-θ)/dt)*a53 +(6θ*(1-θ)/dt)*a54 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +# Predict z8 from z5 and z1 +θ = 1/c5 +dt = c5 + +(1 + (-4θ + 3θ^2) + a51*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a52 +(6θ*(1-θ)/dt)*a53 +(6θ*(1-θ)/dt)*a54 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +=# + +function KenCarp5Tableau(T, T2) + γ = convert(T2, 41 // 200) + a31 = convert(T, 41 // 400) + a32 = -convert(T, 567603406766 // 11931857230679) + a41 = convert(T, 683785636431 // 9252920307686) + a43 = -convert(T, 110385047103 // 1367015193373) + a51 = convert(T, 3016520224154 // 10081342136671) + a53 = convert(T, 30586259806659 // 12414158314087) + a54 = -convert(T, 22760509404356 // 11113319521817) + a61 = convert(T, 218866479029 // 1489978393911) + a63 = convert(T, 638256894668 // 5436446318841) + a64 = -convert(T, 1179710474555 // 5321154724896) + a65 = -convert(T, 60928119172 // 8023461067671) + a71 = convert(T, 1020004230633 // 5715676835656) + a73 = convert(T, 25762820946817 // 25263940353407) + a74 = -convert(T, 2161375909145 // 9755907335909) + a75 = -convert(T, 211217309593 // 5846859502534) + a76 = -convert(T, 4269925059573 // 7827059040749) + a81 = -convert(T, 872700587467 // 9133579230613) + a84 = convert(T, 22348218063261 // 9555858737531) + a85 = -convert(T, 1143369518992 // 8141816002931) + a86 = -convert(T, 39379526789629 // 19018526304540) + a87 = convert(T, 32727382324388 // 42900044865799) + # bhat1 = -convert(T,975461918565//9796059967033) + # bhat4 = convert(T,78070527104295//32432590147079) + # bhat5 = -convert(T,548382580838//3424219808633) + # bhat6 = -convert(T,33438840321285//15594753105479) + # bhat7 = convert(T,3629800801594//4656183773603) + # bhat8 = convert(T,4035322873751//18575991585200) + btilde1 = -convert(T, 360431431567533808054934 // 89473089856732078284381229) # bhat1-a81 + btilde4 = convert(T, 21220331609936495351431026 // 309921249937726682547321949) # bhat4-a84 + btilde5 = -convert(T, 42283193605833819490634 // 2144566741190883522084871) # bhat5-a85 + btilde6 = -convert(T, 21843466548811234473856609 // 296589222149359214696574660) # bhat6-a86 + btilde7 = convert(T, 3333910710978735057753642 // 199750492790973993533703797) # bhat7-a87 + btilde8 = convert(T, 45448919757 // 3715198317040) # bhat8-γ + c3 = convert(T2, 2935347310677 // 11292855782101) + c4 = convert(T2, 1426016391358 // 7196633302097) + c5 = convert(T2, 92 // 100) + c6 = convert(T2, 24 // 100) + c7 = convert(T2, 3 // 5) + α31 = convert(T2, 169472355998441 // 463007087066141) + α32 = convert(T2, 293534731067700 // 463007087066141) + α41 = convert(T2, 152460326250177 // 295061965385977) + α42 = convert(T2, 142601639135800 // 295061965385977) + α51 = convert(T2, -51 // 41) + α52 = convert(T2, 92 // 41) + α61 = convert(T2, 17 // 41) + α62 = convert(T2, 24 // 41) + α71 = convert(T2, 13488091065527792 // 122659689776876057) + α72 = convert(T2, -3214953045 // 3673655312) + α73 = convert(T2, 550552676519862000 // 151043064207496529) + α74 = convert(T2, -409689169278408000 // 135215758621947439) + α75 = convert(T2, 3345 // 12167) + α81 = convert(T2, 1490668709762032 // 122659689776876057) + α82 = convert(T2, 5358255075 // 14694621248) + α83 = convert(T2, -229396948549942500 // 151043064207496529) + α84 = convert(T2, 170703820532670000 // 135215758621947439) + α85 = convert(T2, 30275 // 24334) + + ea21 = convert(T, 41 // 100) + ea31 = convert(T, 367902744464 // 2072280473677) + ea32 = convert(T, 677623207551 // 8224143866563) + ea41 = convert(T, 1268023523408 // 10340822734521) + ea43 = convert(T, 1029933939417 // 13636558850479) + ea51 = convert(T, 14463281900351 // 6315353703477) + ea53 = convert(T, 66114435211212 // 5879490589093) + ea54 = -convert(T, 54053170152839 // 4284798021562) + ea61 = convert(T, 14090043504691 // 34967701212078) + ea63 = convert(T, 15191511035443 // 11219624916014) + ea64 = -convert(T, 18461159152457 // 12425892160975) + ea65 = -convert(T, 281667163811 // 9011619295870) + ea71 = convert(T, 19230459214898 // 13134317526959) + ea73 = convert(T, 21275331358303 // 2942455364971) + ea74 = -convert(T, 38145345988419 // 4862620318723) + ea75 = -convert(T, 1 // 8) + ea76 = -convert(T, 1 // 8) + ea81 = -convert(T, 19977161125411 // 11928030595625) + ea83 = -convert(T, 40795976796054 // 6384907823539) + ea84 = convert(T, 177454434618887 // 12078138498510) + ea85 = convert(T, 782672205425 // 8267701900261) + ea86 = -convert(T, 69563011059811 // 9646580694205) + ea87 = convert(T, 7356628210526 // 4942186776405) + + eb1 = -convert(T, 872700587467 // 9133579230613) + eb4 = convert(T, 22348218063261 // 9555858737531) + eb5 = -convert(T, 1143369518992 // 8141816002931) + eb6 = -convert(T, 39379526789629 // 19018526304540) + eb7 = convert(T, 32727382324388 // 42900044865799) + eb8 = convert(T, 41 // 200) + + ebtilde1 = -convert(T, 360431431567533808054934 // 89473089856732078284381229) + ebtilde4 = convert(T, 21220331609936495351431026 // 309921249937726682547321949) + ebtilde5 = -convert(T, 42283193605833819490634 // 2144566741190883522084871) + ebtilde6 = -convert(T, 21843466548811234473856609 // 296589222149359214696574660) + ebtilde7 = convert(T, 3333910710978735057753642 // 199750492790973993533703797) + ebtilde8 = convert(T, 45448919757 // 3715198317040) + + KenCarp5Tableau(γ, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, + a71, a73, a74, a75, a76, a81, a84, a85, a86, a87, + c3, c4, c5, c6, c7, α31, α32, α41, α42, α51, α52, + α61, α62, α71, α72, α73, α74, α75, α81, α82, α83, α84, α85, + btilde1, btilde4, btilde5, btilde6, btilde7, btilde8, + ea21, ea31, ea32, ea41, ea43, ea51, ea53, ea54, ea61, ea63, + ea64, ea65, ea71, ea73, ea74, ea75, ea76, ea81, ea83, ea84, + ea85, ea86, ea87, eb1, eb4, eb5, eb6, eb7, eb8, ebtilde1, + ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8) +end + +# Flip them all! + +# ebtilde1 = -Int128(872700587467)//9133579230613 + Int128(975461918565)//9796059967033 +# ebtilde4 = Int128(22348218063261)//9555858737531 - Int128(78070527104295)//32432590147079 +# ebtilde5 = -Int128(1143369518992)//8141816002931 + Int128(548382580838)//3424219808633 +# ebtilde6 = -Int128(39379526789629)//19018526304540 + Int128(33438840321285)//15594753105479 +# ebtilde7 = Int128(32727382324388)//42900044865799 - Int128(3629800801594)//4656183773603 +# ebtilde8 = Int128(41)//200 - Int128(4035322873751)//18575991585200 + +struct ESDIRK54I8L2SATableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + a81::T + a82::T + a83::T + a84::T + a85::T + a86::T + a87::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + btilde8::T +end + +function ESDIRK54I8L2SATableau(T, T2) + γ = convert(T2, 1 // 4) + a31 = convert(T, 1748874742213 // 5795261096931) + a32 = convert(T, 1748874742213 // 5795261096931) + a41 = convert(T, 2426486750897 // 12677310711630) + a42 = convert(T, 2426486750897 // 12677310711630) + a43 = convert(T, -783385356511 // 7619901499812) + a51 = convert(T, 1616209367427 // 5722977998639) + a52 = convert(T, 1616209367427 // 5722977998639) + a53 = convert(T, -211896077633 // 5134769641545) + a54 = convert(T, 464248917192 // 17550087120101) + a61 = convert(T, 1860464898611 // 7805430689312) + a62 = convert(T, 1825204367749 // 7149715425471) + a63 = convert(T, -1289376786583 // 6598860380111) + a64 = convert(T, 55566826943 // 2961051076052) + a65 = convert(T, 1548994872005 // 13709222415197) + a71 = convert(T, 1783640092711 // 14417713428467) + a72 = convert(T, -5781183663275 // 18946039887294) + a73 = convert(T, -57847255876685 // 10564937217081) + a74 = convert(T, 29339178902168 // 9787613280015) + a75 = convert(T, 122011506936853 // 12523522131766) + a76 = convert(T, -60418758964762 // 9539790648093) + a81 = convert(T, 3148564786223 // 23549948766475) + a82 = convert(T, -4152366519273 // 20368318839251) + a83 = convert(T, -143958253112335 // 33767350176582) + a84 = convert(T, 16929685656751 // 6821330976083) + a85 = convert(T, 37330861322165 // 4907624269821) + a86 = convert(T, -103974720808012 // 20856851060343) + a87 = convert(T, -93596557767 // 4675692258479) + c3 = convert(T2, (2 + sqrt(convert(T, 2))) / 4) + c4 = convert(T2, 53 // 100) + c5 = convert(T2, 4 // 5) + c6 = convert(T2, 17 // 25) + c7 = convert(T2, 1) + btilde1 = convert(T, -206948709334490044469698 // 10480001459192469358387375) + btilde2 = convert(T, -38800234036520698435148405 // 193732560740235652447264213) + btilde3 = convert(T, -42312118141829119927717945 // 17651296211698462951718982) + btilde4 = convert(T, 77601425937783402908082927 // 76091823354023603930374324) + btilde5 = convert(T, 7549135156215231570800855 // 1787280796764804347348433) + btilde6 = convert(T, -401514321964993460839314379 // 150599863859115530598736650) + btilde7 = convert(T, 17761325247710183915293664 // 33262552787523086832167825) + btilde8 = convert(T, -25249389576073 // 51072051291964) + ESDIRK54I8L2SATableau(γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + a81, a82, a83, a84, a85, a86, a87, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, + btilde8) +end + +struct ESDIRK436L2SA2Tableau{T, T2} + γ::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T +end + +function ESDIRK436L2SA2Tableau(T, T2) + γ = convert(T, 31 // 125) + a31 = convert(T, -360286518617 // 7014585480527) + a32 = convert(T, -360286518617 // 7014585480527) + a41 = convert(T, -506388693497 // 5937754990171) + a42 = convert(T, -506388693497 // 5937754990171) + a43 = convert(T, 7149918333491 // 13390931526268) + a51 = convert(T, -7628305438933 // 11061539393788) + a52 = convert(T, -7628305438933 // 11061539393788) + a53 = convert(T, 21592626537567 // 14352247503901) + a54 = convert(T, 11630056083252 // 17263101053231) + a61 = convert(T, -12917657251 // 5222094901039) + a62 = convert(T, -12917657251 // 5222094901039) + a63 = convert(T, 5602338284630 // 15643096342197) + a64 = convert(T, 9002339615474 // 18125249312447) + a65 = convert(T, -2420307481369 // 24731958684496) + c3 = convert(T2, 486119545908 // 3346201505189) + c4 = convert(T2, 1043 // 1706) + c5 = convert(T2, 1361 // 1300) + c6 = convert(T2, 1) + btilde1 = convert(T, 5106873525203549881053916 // 63280437666689274586070553) + btilde2 = convert(T, 5106873525203549881053916 // 63280437666689274586070553) + btilde3 = convert(T, -25162027003603428150355757 // 187362381104177276978781327) + btilde4 = convert(T, -4098711186040344850920813 // 204021751328880889263048263) + btilde5 = convert(T, -2403006641348284599749077 // 92621941821407359153398928) + btilde6 = convert(T, 20990421664717 // 1109114971657125) + ESDIRK436L2SA2Tableau(γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + c3, c4, c5, c6, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6) +end + +struct ESDIRK437L2SATableau{T, T2} + γ::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T +end + +function ESDIRK437L2SATableau(T, T2) + γ = convert(T, 1 // 8) + a31 = convert(T, -39188347878 // 1513744654945) + a32 = convert(T, -39188347878 // 1513744654945) + a41 = convert(T, 1748874742213 // 5168247530883) + a42 = convert(T, 1748874742213 // 5168247530883) + a43 = convert(T, -1748874742213 // 5795261096931) + a51 = convert(T, -6429340993097 // 17896796106705) + a52 = convert(T, -6429340993097 // 17896796106705) + a53 = convert(T, 9711656375562 // 10370074603625) + a54 = convert(T, 1137589605079 // 3216875020685) + a61 = convert(T, 405169606099 // 1734380148729) + a62 = convert(T, 405169606099 // 1734380148729) + a63 = convert(T, -264468840649 // 6105657584947) + a64 = convert(T, 118647369377 // 6233854714037) + a65 = convert(T, 683008737625 // 4934655825458) + a71 = convert(T, -5649241495537 // 14093099002237) + a72 = convert(T, -5649241495537 // 14093099002237) + a73 = convert(T, 5718691255176 // 6089204655961) + a74 = convert(T, 2199600963556 // 4241893152925) + a75 = convert(T, 8860614275765 // 11425531467341) + a76 = convert(T, -3696041814078 // 6641566663007) + c3 = convert(T2, 1200237871921 // 16391473681546) + c4 = convert(T2, 1 // 2) + c5 = convert(T2, 395 // 567) + c6 = convert(T2, 89 // 126) + c7 = convert(T2, 1) + btilde1 = convert(T, -14021722784906200638478406 / 88328749927055336625976631) + btilde2 = convert(T, -14021722784906200638478406 / 88328749927055336625976631) + btilde3 = convert(T, 3070711560882459617262660 / 10949513763298336699947229) + btilde4 = convert(T, 815814787991699828720304 / 45161095659596754702440075) + btilde5 = convert(T, 1195088015805686578873824 / 81172597762810000486866617) + btilde6 = convert(T, 740420675674591594133033 / 49448254888661947436093061) + btilde7 = convert(T, -3 / 280) + ESDIRK437L2SATableau(γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) +end + +struct ESDIRK547L2SA2Tableau{T, T2} + γ::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T +end + +function ESDIRK547L2SA2Tableau(T, T2) + γ = convert(T, 23 // 125) + a31 = convert(T, 791020047304 // 3561426431547) + a32 = convert(T, 791020047304 // 3561426431547) + a41 = convert(T, -158159076358 // 11257294102345) + a42 = convert(T, -158159076358 // 11257294102345) + a43 = convert(T, -85517644447 // 5003708988389) + a51 = convert(T, -1653327111580 // 4048416487981) + a52 = convert(T, -1653327111580 // 4048416487981) + a53 = convert(T, 1514767744496 // 9099671765375) + a54 = convert(T, 14283835447591 // 12247432691556) + a61 = convert(T, -4540011970825 // 8418487046959) + a62 = convert(T, -4540011970825 // 8418487046959) + a63 = convert(T, -1790937573418 // 7393406387169) + a64 = convert(T, 10819093665085 // 7266595846747) + a65 = convert(T, 4109463131231 // 7386972500302) + a71 = convert(T, -188593204321 // 4778616380481) + a72 = convert(T, -188593204321 // 4778616380481) + a73 = convert(T, 2809310203510 // 10304234040467) + a74 = convert(T, 1021729336898 // 2364210264653) + a75 = convert(T, 870612361811 // 2470410392208) + a76 = convert(T, -1307970675534 // 8059683598661) + c3 = convert(T2, 7121331996143 // 11335814405378) + c4 = convert(T2, 49 // 453) + c5 = convert(T2, 3706679970760 // 5295570149437) + c6 = convert(T2, 347 // 382) + c7 = convert(T2, 1) + btilde1 = convert(T, 1421105133983177175480607 // 34473265709570096426728110) + btilde2 = convert(T, 1421105133983177175480607 // 34473265709570096426728110) + btilde3 = convert(T, 3109316704168648469186161 // 34649291136493354414563315) + btilde4 = convert(T, -1238536018553705945740781 // 14596994419085808131818547) + btilde5 = convert(T, -2644586096629232150947109 // 35649179736979632279017232) + btilde6 = convert(T, -4528233948360460577182037 // 78128560886623254313643924) + btilde7 = convert(T, 77036761781598 // 1719282803550125) + ESDIRK547L2SA2Tableau(γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + c3, c4, c5, c6, c7, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) +end + +struct ESDIRK659L2SATableau{T, T2} + γ::T + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + a81::T + a82::T + a83::T + a84::T + a85::T + a86::T + a87::T + a94::T + a95::T + a96::T + a97::T + a98::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + c8::T2 + c9::T2 + btilde1::T + btilde2::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + btilde8::T + btilde9::T +end + +function ESDIRK659L2SATableau(T, T2) + γ = convert(T, 2 // 9) + a31 = convert(T, 1 // 9) + a32 = convert(T, -52295652026801 // 1014133226193379) + a41 = convert(T, 37633260247889 // 456511413219805) + a42 = convert(T, -162541608159785 // 642690962402252) + a43 = convert(T, 186915148640310 // 408032288622937) + a51 = convert(T, -37161579357179 // 532208945751958) + a52 = convert(T, -211140841282847 // 266150973773621) + a53 = convert(T, 884359688045285 // 894827558443789) + a54 = convert(T, 845261567597837 // 1489150009616527) + a61 = convert(T, 32386175866773 // 281337331200713) + a62 = convert(T, 498042629717897 // 1553069719539220) + a63 = convert(T, -73718535152787 // 262520491717733) + a64 = convert(T, -147656452213061 // 931530156064788) + a65 = convert(T, -16605385309793 // 2106054502776008) + a71 = convert(T, -38317091100349 // 1495803980405525) + a72 = convert(T, 233542892858682 // 880478953581929) + a73 = convert(T, -281992829959331 // 709729395317651) + a74 = convert(T, -52133614094227 // 895217507304839) + a75 = convert(T, -9321507955616 // 673810579175161) + a76 = convert(T, 79481371174259 // 817241804646218) + a81 = convert(T, -486324380411713 // 1453057025607868) + a82 = convert(T, -1085539098090580 // 1176943702490991) + a83 = convert(T, 370161554881539 // 461122320759884) + a84 = convert(T, 804017943088158 // 886363045286999) + a85 = convert(T, -15204170533868 // 934878849212545) + a86 = convert(T, -248215443403879 // 815097869999138) + a87 = convert(T, 339987959782520 // 552150039467091) + a94 = convert(T, 281246836687281 // 672805784366875) + a95 = convert(T, 250674029546725 // 464056298040646) + a96 = convert(T, 88917245119922 // 798581755375683) + a97 = convert(T, 127306093275639 // 658941305589808) + a98 = convert(T, -319515475352107 // 658842144391777) + c3 = convert(T2, 376327483029687 // 1335600577485745) + c4 = convert(T2, 433625707911282 // 850513180247701) + c5 = convert(T2, 183 // 200) + c6 = convert(T2, 62409086037595 // 296036819031271) + c7 = convert(T2, 81796628710131 // 911762868125288) + c8 = convert(T2, 97 // 100) + c9 = convert(T2, 1) + btilde1 = convert(T, 204006714482445 // 253120897457864) + btilde2 = convert(T, 0) + btilde3 = convert(T, 818062434310719 // 743038324242217) + btilde4 = convert(T, -4352947315360352 // 1695885076290837) + btilde5 = convert(T, 4343240072384756 // 4531602892210441) + btilde6 = convert(T, 3512964806614449 // 5680260981303268) + btilde7 = convert(T, -8547437843719087 // 4555265955453704) + btilde8 = convert(T, -6600542869175559 // 6801491069014681) + btilde9 = convert(T, 1602386750057009 // 6720377925948840) + ESDIRK659L2SATableau(γ, + a31, a32, + a41, a42, a43, + a51, a52, a53, a54, + a61, a62, a63, a64, a65, + a71, a72, a73, a74, a75, a76, + a81, a82, a83, a84, a85, a86, a87, + a94, a95, a96, a97, a98, + c3, c4, c5, c6, c7, c8, c9, + btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, + btilde8, btilde9) +end + +struct SDIRK22Tableau{T} + a::T + α::T + β::T +end + +function SDIRK22Tableau(T) + a = convert(T, 1 - 1 / sqrt(2)) + α = convert(T, -sqrt(2)) + β = convert(T, 1 + sqrt(2)) + SDIRK22Tableau(a, α, β) +end + +struct KenCarp47Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a73::T + a74::T + a75::T + a76::T + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + α21::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 + α43::T2 + α51::T2 + α52::T2 + α61::T2 + α62::T2 + α63::T2 + α71::T2 + α72::T2 + α73::T2 + α74::T2 + α75::T2 + α76::T2 + ea21::T + ea31::T + ea32::T + ea41::T + ea42::T + ea43::T + ea51::T + ea52::T + ea53::T + ea54::T + ea61::T + ea62::T + ea63::T + ea64::T + ea65::T + ea71::T + ea72::T + ea73::T + ea74::T + ea75::T + ea76::T + eb3::T + eb4::T + eb5::T + eb6::T + eb7::T + ebtilde3::T + ebtilde4::T + ebtilde5::T + ebtilde6::T + ebtilde7::T +end + +#= +# KenCarp47 +# Predict z3 from Hermite z2 and z1 + +c2 = 2γ +θ = c3/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z4 from Hermite z3 and z1 +θ = c4/c3 +dt = c3 + +y₀ = uprev +y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ +y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ ++ (6θ*(1-θ)/dt)*(a32*z₂) + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a32 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +# Predict z5 from Hermite z2 and z1 +θ = c5/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z6 from z1 and z3 + +θ = c6/c3 +dt = c3 + +y₀ = uprev +y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ +y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ ++ (6θ*(1-θ)/dt)*(a32*z₂) + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a32 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +Predict last stage from z1 and z6 + +θ = 1/c6 +dt = c6 + +y₀ = uprev +y₁ = uprev + a61*z₁ + a62*z₂ + a63*z₃ + a64*z₄ + a65*z₅ + γ*z₆ +y₁-y₀ = a61*z₁ + a62*z₂ + a63*z₃ + a64*z₄ + a65*z₅ + γ*z₆ + +(1 + (-4θ + 3θ^2) + a61*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₆ ++ (6θ*(1-θ)/dt)*(a62*z₂ + a63*z₃ + a64*z₄ + a65*z₅) + +(1 + (-4θ + 3θ^2) + a61*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a62 +(6θ*(1-θ)/dt)*a63 +(6θ*(1-θ)/dt)*a64 +(6θ*(1-θ)/dt)*a65 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +=# +function KenCarp47Tableau(T, T2) + γ = convert(T2, 1235 // 10000) + a31 = convert(T, 624185399699 // 4186980696204) + a32 = a31 + a41 = convert(T, 1258591069120 // 10082082980243) + a42 = a41 + a43 = -convert(T, 322722984531 // 8455138723562) + a51 = -convert(T, 436103496990 // 5971407786587) + a52 = a51 + a53 = -convert(T, 2689175662187 // 11046760208243) + a54 = convert(T, 4431412449334 // 12995360898505) + a61 = -convert(T, 2207373168298 // 14430576638973) + a62 = a61 + a63 = convert(T, 242511121179 // 3358618340039) + a64 = convert(T, 3145666661981 // 7780404714551) + a65 = convert(T, 5882073923981 // 14490790706663) + #a71 = convert(T,0) + #a72 = convert(T,0) + a73 = convert(T, 9164257142617 // 17756377923965) + a74 = -convert(T, 10812980402763 // 74029279521829) + a75 = convert(T, 1335994250573 // 5691609445217) + a76 = convert(T, 2273837961795 // 8368240463276) + + # bhat3 = convert(T,4469248916618//8635866897933) + # bhat4 = -convert(T,621260224600//4094290005349) + # bhat5 = convert(T,696572312987//2942599194819) + # bhat6 = convert(T,1532940081127//5565293938103) + # bhat7 = convert(T,2441//20000) + btilde3 = convert(T, 216367897668138065439709 // 153341716340757627089664345) # bhat3-a73 + btilde4 = -convert(T, 1719969231640509698414113 // 303097339249411872572263321) # bhat4-a74 + btilde5 = convert(T, 33321949854538424751892 // 16748125370719759490730723) # bhat5-a75 + btilde6 = convert(T, 4033362550194444079469 // 1083063207508329376479196) # bhat6-a76 + btilde7 = -convert(T, 29 // 20000) # bhat7-γ + + #c2 = 2γ + c3 = convert(T2, 4276536705230 // 10142255878289) + c4 = convert(T2, 67 // 200) + c5 = convert(T2, 3 // 40) + c6 = convert(T2, 7 // 10) + + α21 = convert(T2, 2) # c2/γ + α31 = -convert(T2, 796131459065721 // 1125899906842624) + α32 = convert(T2, 961015682954173 // 562949953421312) + α41 = convert(T2, 139710975840363 // 2251799813685248) + α42 = convert(T2, 389969885861609 // 1125899906842624) + α43 = convert(T2, 2664298132243335 // 4503599627370496) + α51 = convert(T2, 6272219723949193 // 9007199254740992) + α52 = convert(T2, 2734979530791799 // 9007199254740992) + α61 = convert(T2, 42616678320173 // 140737488355328) + α62 = -convert(T2, 2617409280098421 // 1125899906842624) + α63 = convert(T2, 1701187880189829 // 562949953421312) + α71 = convert(T2, 4978493057967061 // 2251799813685248) + α72 = convert(T2, 7230365118049293 // 9007199254740992) + α73 = -convert(T2, 6826045129237249 // 18014398509481984) + α74 = -convert(T2, 2388848894891525 // 1125899906842624) + α75 = -convert(T2, 4796744191239075 // 2251799813685248) + α76 = convert(T2, 2946706549191323 // 1125899906842624) + + ea21 = convert(T, 247 // 1000) + ea31 = convert(T, 247 // 4000) + ea32 = convert(T, 2694949928731 // 7487940209513) + ea41 = convert(T, 464650059369 // 8764239774964) + ea42 = convert(T, 878889893998 // 2444806327765) + ea43 = -convert(T, 952945855348 // 12294611323341) + ea51 = convert(T, 476636172619 // 8159180917465) + ea52 = -convert(T, 1271469283451 // 7793814740893) + ea53 = -convert(T, 859560642026 // 4356155882851) + ea54 = convert(T, 1723805262919 // 4571918432560) + ea61 = convert(T, 6338158500785 // 11769362343261) + ea62 = -convert(T, 4970555480458 // 10924838743837) + ea63 = convert(T, 3326578051521 // 2647936831840) + ea64 = -convert(T, 880713585975 // 1841400956686) + ea65 = -convert(T, 1428733748635 // 8843423958496) + ea71 = convert(T, 760814592956 // 3276306540349) + ea72 = convert(T, 760814592956 // 3276306540349) + ea73 = -convert(T, 47223648122716 // 6934462133451) + ea74 = convert(T, 71187472546993 // 9669769126921) + ea75 = -convert(T, 13330509492149 // 9695768672337) + ea76 = convert(T, 11565764226357 // 8513123442827) + + #eb1 = 0 + #eb2 = 0 + eb3 = convert(T, 9164257142617 // 17756377923965) + eb4 = -convert(T, 10812980402763 // 74029279521829) + eb5 = convert(T, 1335994250573 // 5691609445217) + eb6 = convert(T, 2273837961795 // 8368240463276) + eb7 = convert(T, 247 // 2000) + + #ebtilde1 = 0 + #ebtilde2 = 0 + ebtilde3 = convert(T, 216367897668138065439709 // 153341716340757627089664345) + ebtilde4 = -convert(T, 1719969231640509698414113 // 303097339249411872572263321) + ebtilde5 = convert(T, 33321949854538424751892 // 16748125370719759490730723) + ebtilde6 = convert(T, 4033362550194444079469 // 1083063207508329376479196) + ebtilde7 = -convert(T, 29 // 20000) + + KenCarp47Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, a73, a74, a75, a76, + btilde3, btilde4, btilde5, btilde6, btilde7, + c3, c4, c5, c6, + α21, α31, α32, α41, α42, α43, α51, α52, α61, α62, α63, α71, α72, α73, + α74, α75, α76, + ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, + ea63, ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76, eb3, eb4, eb5, + eb6, eb7, ebtilde3, ebtilde4, + ebtilde5, ebtilde6, ebtilde7) +end +struct KenCarp58Tableau{T, T2} + γ::T2 + a31::T + a32::T + a41::T + a42::T + a43::T + a51::T + a52::T + a53::T + a54::T + a61::T + a62::T + a63::T + a64::T + a65::T + a71::T + a72::T + a73::T + a74::T + a75::T + a76::T + a83::T + a84::T + a85::T + a86::T + a87::T + c3::T2 + c4::T2 + c5::T2 + c6::T2 + c7::T2 + α31::T2 + α32::T2 + α41::T2 + α42::T2 + α51::T2 + α52::T2 + α61::T2 + α62::T2 + α63::T2 + α71::T2 + α72::T2 + α73::T2 + α81::T2 + α82::T2 + α83::T2 + α84::T2 + α85::T2 + α86::T2 + α87::T2 + btilde3::T + btilde4::T + btilde5::T + btilde6::T + btilde7::T + btilde8::T + ea21::T + ea31::T + ea32::T + ea41::T + ea42::T + ea43::T + ea51::T + ea52::T + ea53::T + ea54::T + ea61::T + ea62::T + ea63::T + ea64::T + ea65::T + ea71::T + ea72::T + ea73::T + ea74::T + ea75::T + ea76::T + ea81::T + ea82::T + ea83::T + ea84::T + ea85::T + ea86::T + ea87::T + eb3::T + eb4::T + eb5::T + eb6::T + eb7::T + eb8::T + ebtilde3::T + ebtilde4::T + ebtilde5::T + ebtilde6::T + ebtilde7::T + ebtilde8::T +end + +#= +# KenCarp5 +# Predict z3 from Hermite z2 and z1 + +c2 = 2γ +θ = c3/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z4 from z2 and z1 +θ = c4/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z5 from z2 and z1 +θ = c5/c2 +dt = c2 +((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) +((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) + +# Predict z6 from z3 and z1 +θ = c6/c3 +dt = c3 + +y₀ = uprev +y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ +y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ ++ (6θ*(1-θ)/dt)*(a32*z₂) + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a32 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +# Predict z7 from z3 and z1 +θ = c7/c3 +dt = c3 + +(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) +y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ ++ (6θ*(1-θ)/dt)*(a32*z₂) + +(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a32 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +# Predict z8 from z7 and z1 +θ = 1/c7 +dt = c7 + +(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) +y₁-y₀ = a71*z₁ + a72*z₂ + a73*z₃ + a74*z₄ + a75*z₅ + a76*z₆ + γ*z₇ + +(1 + (-4θ + 3θ^2) + a71*(6θ*(1-θ)/dt))*z₁ + +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₇ ++ (6θ*(1-θ)/dt)*(a72*z₂ + a73*z₃ + a74*z₄ + a75*z₅ + a76*z₆) + +(1 + (-4θ + 3θ^2) + a71*(6θ*(1-θ)/dt)) +(6θ*(1-θ)/dt)*a72 +(6θ*(1-θ)/dt)*a73 +(6θ*(1-θ)/dt)*a74 +(6θ*(1-θ)/dt)*a75 +(6θ*(1-θ)/dt)*a76 +(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) + +=# + +function KenCarp58Tableau(T, T2) + γ = convert(T2, 2 // 9) + a31 = convert(T, 2366667076620 // 8822750406821) + a32 = a31 + a41 = -convert(T, 257962897183 // 4451812247028) + a42 = a41 + a43 = convert(T, 128530224461 // 14379561246022) + a51 = -convert(T, 486229321650 // 11227943450093) + a52 = a51 + a53 = -convert(T, 225633144460 // 6633558740617) + a54 = convert(T, 1741320951451 // 6824444397158) + a61 = convert(T, 621307788657 // 4714163060173) + a62 = a61 + a63 = -convert(T, 125196015625 // 3866852212004) + a64 = convert(T, 940440206406 // 7593089888465) + a65 = convert(T, 961109811699 // 6734810228204) + a71 = convert(T, 2036305566805 // 6583108094622) + a72 = a71 + a73 = -convert(T, 3039402635899 // 4450598839912) + a74 = -convert(T, 1829510709469 // 31102090912115) + a75 = -convert(T, 286320471013 // 6931253422520) + a76 = convert(T, 8651533662697 // 9642993110008) + a83 = convert(T, 3517720773327 // 20256071687669) + a84 = convert(T, 4569610470461 // 17934693873752) + a85 = convert(T, 2819471173109 // 11655438449929) + a86 = convert(T, 3296210113763 // 10722700128969) + a87 = -convert(T, 1142099968913 // 5710983926999) + + # bhat3 = convert(T,520639020421//8300446712847) + # bhat4 = convert(T,4550235134915//17827758688493) + # bhat5 = convert(T,1482366381361//6201654941325) + # bhat6 = convert(T,5551607622171//13911031047899) + # bhat7 = -convert(T,5266607656330//36788968843917) + # bhat8 = convert(T,1074053359553//5740751784926) + + btilde3 = -convert(T, 18652552508630163520943320 // 168134443655105334713783643) # bhat3-a83 + btilde4 = convert(T, 141161430501477620145807 // 319735394533244397237135736) # bhat4-a84 + btilde5 = -convert(T, 207757214437709595456056 // 72283007456311581445415925) # bhat5-a85 + btilde6 = convert(T, 13674542533282477231637762 // 149163814411398370516486131) # bhat6-a86 + btilde7 = convert(T, 11939168497868428048898551 // 210101209758476969753215083) # bhat7-a87 + btilde8 = -convert(T, 1815023333875 // 51666766064334) # bhat8-γ + #c2 = 2γ + c3 = convert(T2, 6456083330201 // 8509243623797) + c4 = convert(T2, 1632083962415 // 14158861528103) + c5 = convert(T2, 6365430648612 // 17842476412687) + c6 = convert(T2, 18 // 25) + c7 = convert(T2, 191 // 200) + + α31 = -convert(T2, 796131459065721 // 1125899906842624) + α32 = convert(T2, 961015682954173 // 562949953421312) + α41 = convert(T2, 3335563016633385 // 4503599627370496) + α42 = convert(T2, 2336073221474223 // 9007199254740992) + α51 = convert(T2, 1777088537295433 // 9007199254740992) + α52 = convert(T2, 7230110717445555 // 9007199254740992) + α61 = convert(T2, 305461594360167 // 36028797018963968) + α62 = convert(T2, 3700851199347703 // 36028797018963968) + α63 = convert(T2, 8005621056314023 // 9007199254740992) + α71 = convert(T2, 247009276011491 // 9007199254740992) + α72 = -convert(T2, 6222030107065861 // 9007199254740992) + α73 = convert(T2, 1872777510724421 // 1125899906842624) + α81 = convert(T2, 180631849429283 // 36028797018963968) + α82 = -convert(T2, 3454740038041085 // 36028797018963968) + α83 = convert(T2, 476708848972457 // 2251799813685248) + α84 = convert(T2, 5255799236757313 // 288230376151711744) + α85 = convert(T2, 3690914796734375 // 288230376151711744) + α86 = -convert(T2, 5010195363762467 // 18014398509481984) + α87 = convert(T2, 5072201887169367 // 4503599627370496) + + ea21 = convert(T, 4 // 9) + ea31 = convert(T, 1 // 9) + ea32 = convert(T, 1183333538310 // 1827251437969) + ea41 = convert(T, 895379019517 // 9750411845327) + ea42 = convert(T, 477606656805 // 13473228687314) + ea43 = -convert(T, 112564739183 // 9373365219272) + ea51 = -convert(T, 4458043123994 // 13015289567637) + ea52 = -convert(T, 2500665203865 // 9342069639922) + ea53 = convert(T, 983347055801 // 8893519644487) + ea54 = convert(T, 2185051477207 // 2551468980502) + ea61 = -convert(T, 167316361917 // 17121522574472) + ea62 = convert(T, 1605541814917 // 7619724128744) + ea63 = convert(T, 991021770328 // 13052792161721) + ea64 = convert(T, 2342280609577 // 11279663441611) + ea65 = convert(T, 3012424348531 // 12792462456678) + ea71 = convert(T, 6680998715867 // 14310383562358) + ea72 = convert(T, 5029118570809 // 3897454228471) + ea73 = convert(T, 2415062538259 // 6382199904604) + ea74 = -convert(T, 3924368632305 // 6964820224454) + ea75 = -convert(T, 4331110370267 // 15021686902756) + ea76 = -convert(T, 3944303808049 // 11994238218192) + ea81 = convert(T, 2193717860234 // 3570523412979) + ea82 = convert(T, 2193717860234 // 3570523412979) + ea83 = convert(T, 5952760925747 // 18750164281544) + ea84 = -convert(T, 4412967128996 // 6196664114337) + ea85 = convert(T, 4151782504231 // 36106512998704) + ea86 = convert(T, 572599549169 // 6265429158920) + ea87 = -convert(T, 457874356192 // 11306498036315) + + eb3 = convert(T, 3517720773327 // 20256071687669) + eb4 = convert(T, 4569610470461 // 17934693873752) + eb5 = convert(T, 2819471173109 // 11655438449929) + eb6 = convert(T, 3296210113763 // 10722700128969) + eb7 = -convert(T, 1142099968913 // 5710983926999) + eb8 = convert(T, 2 // 9) + + ebtilde3 = -convert(T, 18652552508630163520943320 // 168134443655105334713783643)#bhat3-eb3 + ebtilde4 = convert(T, 141161430501477620145807 // 319735394533244397237135736) #bhat4-eb4 + ebtilde5 = -convert(T, 207757214437709595456056 // 72283007456311581445415925) #bhat5-eb5 + ebtilde6 = convert(T, 13674542533282477231637762 // 149163814411398370516486131) #bhat6-eb6 + ebtilde7 = convert(T, 11939168497868428048898551 // 210101209758476969753215083) #bhat7-eb7 + ebtilde8 = -convert(T, 1815023333875 // 51666766064334) #bhat8-eb8 + + KenCarp58Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, + a65, + a71, a72, a73, a74, a75, a76, a83, a84, a85, a86, a87, + c3, c4, c5, c6, c7, α31, α32, α41, α42, α51, α52, + α61, α62, α63, α71, α72, α73, α81, α82, α83, α84, α85, α86, α87, + btilde3, btilde4, btilde5, btilde6, btilde7, btilde8, + ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, + ea63, + ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, + ea85, ea86, ea87, eb3, eb4, eb5, eb6, eb7, eb8, ebtilde3, + ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8) +end diff --git a/test/algconvergence/ode_firk_tests.jl b/test/algconvergence/ode_firk_tests.jl new file mode 100644 index 0000000000..ade18509a8 --- /dev/null +++ b/test/algconvergence/ode_firk_tests.jl @@ -0,0 +1,54 @@ +using OrdinaryDiffEq, DiffEqDevTools, Test, LinearAlgebra +import ODEProblemLibrary: prob_ode_linear, prob_ode_2Dlinear, van + +testTol = 0.2 + +for prob in [prob_ode_linear, prob_ode_2Dlinear] + sim21 = test_convergence(1 .// 2 .^ (6:-1:3), prob, RadauIIA5()) + @test sim21.𝒪est[:final]≈5 atol=testTol +end + +# test adaptivity +for iip in (true, false) + if iip + vanstiff = ODEProblem{iip}(van, [0; sqrt(3)], (0.0, 1.0), 1e6) + else + vanstiff = ODEProblem{false}((u, p, t) -> van(u, p, t), [0; sqrt(3)], (0.0, 1.0), + 1e6) + end + sol = solve(vanstiff, RadauIIA5()) + if iip + @test sol.stats.naccept + sol.stats.nreject > sol.stats.njacs # J reuse + @test sol.stats.njacs < sol.stats.nw # W reuse + end + @test length(sol) < 150 + @test length(solve(remake(vanstiff, p = 1e7), RadauIIA5())) < 150 + @test length(solve(remake(vanstiff, p = 1e7), reltol = [1e-4, 1e-6], RadauIIA5())) < 170 + @test length(solve(remake(vanstiff, p = 1e7), RadauIIA5(), reltol = 1e-9, + abstol = 1e-9)) < 870 + @test length(solve(remake(vanstiff, p = 1e9), RadauIIA5())) < 170 + @test length(solve(remake(vanstiff, p = 1e10), RadauIIA5())) < 190 +end + +##Tests for RadauIIA3 +for prob in [prob_ode_linear, prob_ode_2Dlinear] + dts = 1 ./ 2 .^ (8:-1:1) + sim = test_convergence(dts, prob, RadauIIA3()) + @test sim.𝒪est[:final]≈3 atol=0.25 +end + +# test adaptivity +for iip in (true, false) + if iip + vanstiff = ODEProblem{iip}(van, [0; sqrt(3)], (0.0, 1.0), 1e6) + else + vanstiff = ODEProblem{false}((u, p, t) -> van(u, p, t), [0; sqrt(3)], (0.0, 1.0), + 1e6) + end + sol = solve(vanstiff, RadauIIA3()) + if iip + @test sol.stats.naccept + sol.stats.nreject > sol.stats.njacs # J reuse + @test sol.stats.njacs < sol.stats.nw # W reuse + end + @test length(sol) < 5000 # the error estimate is not very good +end diff --git a/test/algconvergence/ode_rosenbrock_tests.jl b/test/algconvergence/ode_rosenbrock_tests.jl new file mode 100644 index 0000000000..e71ec00355 --- /dev/null +++ b/test/algconvergence/ode_rosenbrock_tests.jl @@ -0,0 +1,706 @@ +using OrdinaryDiffEq, DiffEqDevTools, Test, LinearAlgebra, LinearSolve +import ODEProblemLibrary: prob_ode_linear, + prob_ode_2Dlinear, + prob_ode_bigfloatlinear, prob_ode_bigfloat2Dlinear +import LinearSolve + +@testset "Rosenbrock Tests" begin + ## Breakout these since no other test of their adaptivity + + dts = (1 / 2) .^ (6:-1:3) + testTol = 0.2 + + ### Rosenbrock23() + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Rosenbrock23()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, Rosenbrock23()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rosenbrock23()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, Rosenbrock23()) + @test length(sol) < 20 + + prob = prob_ode_bigfloat2Dlinear + + sim = test_convergence(dts, prob, Rosenbrock23(linsolve = QRFactorization())) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, Rosenbrock23(linsolve = QRFactorization())) + @test length(sol) < 20 + + ### Rosenbrock32() + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Rosenbrock32()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, Rosenbrock32()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rosenbrock32()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, Rosenbrock32()) + @test length(sol) < 20 + + ### ROS3P() + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS3P()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3P()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS3P()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3P()) + @test length(sol) < 20 + + ### Rodas3() + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Rodas3()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, Rodas3()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas3()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, Rodas3()) + @test length(sol) < 20 + + ### ROS2 + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS2()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, ROS2()) + @test length(sol) < 61 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS2()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, ROS2PR()) + @test length(sol) < 60 + + ### ROS2PR + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS2PR()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, ROS2PR()) + @test length(sol) < 30 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS2PR()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, ROS2PR()) + @test length(sol) < 30 + + ### ROS2S + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS2S()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, ROS2S()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS2S()) + @test sim.𝒪est[:final]≈2 atol=testTol + + sol = solve(prob, ROS2S()) + @test length(sol) < 20 + + ### ROS3 + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS3()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS3()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3()) + @test length(sol) < 20 + + ### ROS3PR + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS3PR()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3PR()) + @test length(sol) < 20 #length(sol) = 4 => Too Small?? + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS3PR()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3PR()) + @test length(sol) < 20 #length(sol) = 4 => Too Small?? + + ### Scholz4_7 + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Scholz4_7()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, Scholz4_7()) + @test length(sol) < 30 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Scholz4_7()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, Scholz4_7()) + @test length(sol) < 30 + + println("4th order Rosenbrocks") + + ### RosShamp4 + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, RosShamp4()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, RosShamp4()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, RosShamp4()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, RosShamp4()) + @test length(sol) < 20 + + ### Veldd4 + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Veldd4()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, Veldd4()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Veldd4()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, Veldd4()) + @test length(sol) < 20 + + ### Velds4 + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Velds4()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, Velds4()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Velds4()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, Velds4()) + @test length(sol) < 20 + + ### GRK4T + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, GRK4T()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, GRK4T()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, GRK4T()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, GRK4T()) + @test length(sol) < 20 + + ### GRK4A + dts = (1 / 2) .^ (7:-1:4) + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, GRK4A()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, GRK4A()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, GRK4A()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, GRK4A()) + @test length(sol) < 20 + + ### Ros4LStab + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Ros4LStab()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, Ros4LStab()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Ros4LStab()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, Ros4LStab()) + @test length(sol) < 20 + + ### Rosenbrock-W Algorithms + + println("Rosenbrock-W") + + ### ROS34PW1a + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS34PW1a()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PW1a()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS34PW1a()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PW1a()) + @test length(sol) < 20 + + ### ROS34PW1b + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS34PW1b()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PW1b()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS34PW1b()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PW1b()) + @test length(sol) < 20 + + ### ROS34PW2 + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS34PW2()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PW2()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS34PW2()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PW2()) + @test length(sol) < 20 + + ### ROS34PW3 + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS34PW3()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, ROS34PW3()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS34PW3()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, ROS34PW3()) + @test length(sol) < 20 + + ### ROS34PRw + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS34PRw()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PRw()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS34PRw()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS34PRw()) + @test length(sol) < 20 + + ### ROS3PRL + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS3PRL()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3PRL()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS3PRL()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3PRL()) + @test length(sol) < 20 + + ### ROS3PRL2 + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROS3PRL2()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3PRL2()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROS3PRL2()) + @test sim.𝒪est[:final]≈3 atol=testTol + + sol = solve(prob, ROS3PRL2()) + @test length(sol) < 20 + + ### ROK4a + prob = prob_ode_linear + + sim = test_convergence(dts, prob, ROK4a()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, ROK4a()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, ROK4a()) + @test sim.𝒪est[:final]≈4 atol=testTol + + sol = solve(prob, ROK4a()) + @test length(sol) < 20 + + ### RosenbrockW6S4OS + sim = test_convergence(dts, prob, RosenbrockW6S4OS())#test inplace + @test sim.𝒪est[:final]≈4 atol=testTol + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, RosenbrockW6S4OS())#test non-inplace + @test sim.𝒪est[:final]≈4 atol=testTol + + ### Rodas23W, Rodas3P + + println("Rodas23W") + + prob = prob_ode_linear + + dts = (1 / 2) .^ (6:-1:3) + sim = test_convergence(dts, prob, Rodas23W(), dense_errors = true) + @test sim.𝒪est[:final]≈2 atol=testTol + @test sim.𝒪est[:L2]≈2 atol=testTol + + sol = solve(prob, Rodas23W()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas23W(), dense_errors = true) + @test sim.𝒪est[:final]≈2 atol=testTol + @test sim.𝒪est[:L2]≈2 atol=testTol + + sol = solve(prob, Rodas23W()) + @test length(sol) < 20 + + println("Rodas3P") + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Rodas3P(), dense_errors = true) + @test sim.𝒪est[:final]≈3 atol=testTol + @test sim.𝒪est[:L2]≈3 atol=testTol + + sol = solve(prob, Rodas3P()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas3P(), dense_errors = true) + @test sim.𝒪est[:final]≈3 atol=testTol + @test sim.𝒪est[:L2]≈3 atol=testTol + + sol = solve(prob, Rodas3P()) + @test length(sol) < 20 + + ### Rodas4 Algorithms + + println("RODAS") + + dts = (1 / 2) .^ (7:-1:4) + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Rodas4(), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4()) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas4(autodiff = false), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4(autodiff = false)) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas42(), dense_errors = true) + @test sim.𝒪est[:final]≈5.1 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas42()) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas4P(), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4P()) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas4P2(), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4P2()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas4(), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4()) + @test length(sol) < 20 + + println("Rodas4 with finite diff") + + sim = test_convergence(dts, prob, Rodas4(autodiff = false), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4(autodiff = false)) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas4(autodiff = false, + diff_type = Val{:forward}), + dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4(autodiff = false, diff_type = Val{:forward})) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas4(autodiff = false, + diff_type = Val{:complex}), + dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4(autodiff = false, diff_type = Val{:complex})) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas42(), dense_errors = true) + @test sim.𝒪est[:final]≈5 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas42()) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas4P(), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4P()) + @test length(sol) < 20 + + sim = test_convergence(dts, prob, Rodas4P2(), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4P2()) + @test length(sol) < 20 + + println("Rodas4P2 with finite diff") + + sim = test_convergence(dts, prob, Rodas4P2(autodiff = false), dense_errors = true) + @test sim.𝒪est[:final]≈4 atol=testTol + @test sim.𝒪est[:L2]≈4 atol=testTol + + sol = solve(prob, Rodas4P2(autodiff = false)) + @test length(sol) < 20 + + ### Rodas5 + println("Rodas5") + + prob = prob_ode_linear + + dts = (1 / 2) .^ (6:-1:3) + sim = test_convergence(dts, prob, Rodas5(), dense_errors = true) + @test sim.𝒪est[:final]≈5 atol=testTol + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas5(), dense_errors = true) + @test sim.𝒪est[:final]≈5 atol=testTol + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5()) + @test length(sol) < 20 + + println("Rodas5P") + + prob = prob_ode_linear + + dts = (1 / 2) .^ (5:-1:2) + sim = test_convergence(dts, prob, Rodas5P(), dense_errors = true) + #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5P()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas5P(), dense_errors = true) + #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5P()) + @test length(sol) < 20 + + println("Rodas5Pe") + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Rodas5Pe(), dense_errors = true) + #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5Pe()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas5Pe(), dense_errors = true) + #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5Pe()) + @test length(sol) < 20 + + println("Rodas5Pr") + + prob = prob_ode_linear + + sim = test_convergence(dts, prob, Rodas5Pr(), dense_errors = true) + #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5Pr()) + @test length(sol) < 20 + + prob = prob_ode_2Dlinear + + sim = test_convergence(dts, prob, Rodas5Pr(), dense_errors = true) + #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 + @test sim.𝒪est[:L2]≈5 atol=testTol + + sol = solve(prob, Rodas5Pr()) + @test length(sol) < 20 + + prob = ODEProblem((u, p, t) -> 0.9u, 0.1, (0.0, 1.0)) + @test_nowarn solve(prob, Rosenbrock23(autodiff = false)) +end + +@testset "Convergence with time-dependent matrix-free Jacobian" begin + time_derivative(du, u, p, t) = (du[1] = t * u[1]) + time_derivative_analytic(u0, p, t) = u0 * exp(t^2 / 2) + ff_time_derivative = ODEFunction(time_derivative, analytic = time_derivative_analytic) + prob = ODEProblem(ff_time_derivative, [1.0], (0.0, 1.0)) + + dts = (1 / 2) .^ (6:-1:3) + testTol = 0.2 + # Check convergence of Rodas3 with time-dependent matrix-free Jacobian. + # Primarily to check that the Jacobian is being updated correctly as t changes. + sim = test_convergence(dts, prob, Rodas3(linsolve = LinearSolve.KrylovJL())) + @test sim.𝒪est[:final]≈3 atol=testTol +end diff --git a/test/algconvergence/owrenzen_tests.jl b/test/algconvergence/owrenzen_tests.jl new file mode 100644 index 0000000000..35d4a5b3a9 --- /dev/null +++ b/test/algconvergence/owrenzen_tests.jl @@ -0,0 +1,43 @@ +using OrdinaryDiffEq, DiffEqDevTools, DiffEqBase, Test, Random +import ODEProblemLibrary: prob_ode_2Dlinear, prob_ode_linear + +Random.seed!(100) +## Convergence Testing +dts = (1 / 2) .^ (7:-1:4) +testTol = 0.2 + +prob = prob_ode_linear +sol = solve(prob, OwrenZen3()) +@test length(sol) < 20 +sol = solve(prob, OwrenZen4()) +@test length(sol) < 20 +sol = solve(prob, OwrenZen5()) +@test length(sol) < 20 + +sim = test_convergence(dts, prob, OwrenZen3(), dense_errors = true) +@test sim.𝒪est[:final]≈3 atol=testTol +@test sim.𝒪est[:L2]≈3 atol=testTol +sim = test_convergence(dts, prob, OwrenZen4(), dense_errors = true) +@test sim.𝒪est[:final]≈4 atol=testTol +@test sim.𝒪est[:L2]≈4 atol=testTol +sim = test_convergence(dts, prob, OwrenZen5(), dense_errors = true) +@test sim.𝒪est[:final]≈5 atol=testTol +@test sim.𝒪est[:L2]≈5 atol=testTol + +prob = prob_ode_2Dlinear +sol = solve(prob, OwrenZen3()) +@test length(sol) < 20 +sol = solve(prob, OwrenZen4()) +@test length(sol) < 20 +sol = solve(prob, OwrenZen5()) +@test length(sol) < 20 + +sim = test_convergence(dts, prob, OwrenZen3(), dense_errors = true) +@test sim.𝒪est[:final]≈3 atol=testTol +@test sim.𝒪est[:L2]≈3 atol=testTol +sim = test_convergence(dts, prob, OwrenZen4(), dense_errors = true) +@test sim.𝒪est[:final]≈4 atol=testTol +@test sim.𝒪est[:L2]≈4 atol=testTol +sim = test_convergence(dts, prob, OwrenZen5(), dense_errors = true) +@test sim.𝒪est[:final]≈5 atol=testTol +@test sim.𝒪est[:L2]≈5 atol=testTol diff --git a/test/runtests.jl b/test/runtests.jl index 4825163319..1dbd745f77 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -71,54 +71,6 @@ function activate_symplectic_rk() Pkg.instantiate() end -function activate_default() - Pkg.activate("../lib/OrdinaryDiffEqDefault") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - -function activate_rosenbrock() - Pkg.activate("../lib/OrdinaryDiffEqRosenbrock") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - -function activate_firk() - Pkg.activate("../lib/OrdinaryDiffEqFIRK") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - -function activate_sdirk() - Pkg.activate("../lib/OrdinaryDiffEqSDIRK") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - -function activate_explicit_rk() - Pkg.activate("../lib/OrdinaryDiffEqExplicitRK") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - -function activate_bdf() - Pkg.activate("../lib/OrdinaryDiffEqBDF") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - -function low_order_rk() - Pkg.activate("../lib/OrdinaryDiffEqLowOrderRK") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - -function high_order_rk() - Pkg.activate("../lib/OrdinaryDiffEqHighOrderRK") - Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() -end - #Start Test Script @time begin @@ -242,27 +194,20 @@ end end if !is_APPVEYOR && GROUP == "AlgConvergence_II" - @time @safetestset "OwrenZen Tests" include("../lib/OrdinaryLowOrderRK/test/owrenzen_tests.jl") + @time @safetestset "OwrenZen Tests" include("algconvergence/owrenzen_tests.jl") @time @safetestset "Runge-Kutta-Chebyshev Tests" include("../lib/OrdinaryDiffEqStabilizedRK/test/rkc_tests.jl") end if !is_APPVEYOR && GROUP == "AlgConvergence_III" @time @safetestset "Linear Methods Tests" include("algconvergence/linear_method_tests.jl") @time @safetestset "Split Methods Tests" include("algconvergence/split_methods_tests.jl") + @time @safetestset "Rosenbrock Tests" include("algconvergence/ode_rosenbrock_tests.jl") + @time @safetestset "FIRK Tests" include("algconvergence/ode_firk_tests.jl") @time @safetestset "Linear-Nonlinear Methods Tests" include("algconvergence/linear_nonlinear_convergence_tests.jl") @time @safetestset "Linear-Nonlinear Krylov Methods Tests" include("algconvergence/linear_nonlinear_krylov_tests.jl") @time @safetestset "Quadruple precision Runge-Kutta Tests" include("algconvergence/ode_quadruple_precision_tests.jl") end - if !is_APPVEYOR && GROUP == "FIRK" - @time @safetestset "FIRK Tests" include("../lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl") - end - - - if !is_APPVEYOR && GROUP == "Rosenbrock" - @time @safetestset "Rosenbrock Tests" include("../lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl") - end - if !is_APPVEYOR && GROUP == "Symplectic" @time @safetestset "Symplectic Tests" include("../lib/OrdinaryDiffEqSymplecticRK/test/symplectic_tests.jl") end From 7348adb34e532493d56887da668ff7cdb5866e6b Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 23:02:18 +0530 Subject: [PATCH 025/112] Fixes --- lib/OrdinaryDiffEqBDF/Project.toml | 22 - .../src/OrdinaryDiffEqBDF.jl | 25 - lib/OrdinaryDiffEqBDF/src/alg_utils.jl | 23 - lib/OrdinaryDiffEqBDF/src/algorithms.jl | 223 -- lib/OrdinaryDiffEqBDF/src/bdf_caches.jl | 658 ---- lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl | 1345 ------- lib/OrdinaryDiffEqExplicitRK/Project.toml | 24 - .../src/OrdinaryDiffEqExplicitRK.jl | 22 - lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl | 7 - .../src/algorithms.jl | 6 - .../src/explicit_rk_caches.jl | 60 - .../src/explicit_rk_perform_step.jl | 240 -- lib/OrdinaryDiffEqFIRK/Project.toml | 22 - .../src/OrdinaryDiffEqFIRK.jl | 27 - lib/OrdinaryDiffEqFIRK/src/alg_utils.jl | 7 - lib/OrdinaryDiffEqFIRK/src/algorithms.jl | 106 - lib/OrdinaryDiffEqFIRK/src/controllers.jl | 25 - lib/OrdinaryDiffEqFIRK/src/firk_caches.jl | 275 -- .../src/firk_perform_step.jl | 751 ---- lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl | 112 - .../src/integrator_interface.jl | 4 - lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl | 54 - lib/OrdinaryDiffEqFIRK/test/runtests.jl | 3 - lib/OrdinaryDiffEqHighOrderRK/Project.toml | 22 - .../src/OrdinaryHighOrderRK.jl | 27 - .../src/alg_utils.jl | 11 - .../src/algorithms.jl | 61 - .../src/high_order_rk_addsteps.jl | 259 -- .../src/high_order_rk_caches.jl | 265 -- .../src/high_order_rk_perform_step.jl | 1153 ------ .../src/high_order_rk_tableaus.jl | 1406 -------- .../src/interp_func.jl | 6 - .../src/interpolants.jl | 138 - lib/OrdinaryDiffEqLowOrderRK/Project.toml | 22 - .../src/OrdinaryDiffEqLowOrderRK.jl | 33 - lib/OrdinaryDiffEqLowOrderRK/src/alg_utils.jl | 47 - .../src/algorithms.jl | 632 ---- .../src/fixed_timestep_perform_step.jl | 487 --- .../src/interp_func.jl | 52 - .../src/interpolants.jl | 1536 -------- .../src/low_order_rk_addsteps.jl | 715 ---- .../src/low_order_rk_caches.jl | 1561 -------- .../src/low_order_rk_perform_step.jl | 2326 ------------ .../src/low_order_rk_tableaus.jl | 2186 ------------ .../src/split_perform_step.jl | 50 - .../test/owrenzen_tests.jl | 43 - lib/OrdinaryDiffEqLowOrderRK/test/runtests.jl | 0 lib/OrdinaryDiffEqRosenbrock/Project.toml | 20 - .../src/OrdinaryDiffEqRosenbrock.jl | 31 - lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl | 68 - .../src/algorithms.jl | 208 -- .../src/generic_rosenbrock.jl | 1810 ---------- .../src/integrator_interface.jl | 34 - .../src/integrator_utils.jl | 32 - .../src/interp_func.jl | 28 - .../src/rosenbrock_caches.jl | 1143 ------ .../src/rosenbrock_interpolants.jl | 367 -- .../src/rosenbrock_perform_step.jl | 1989 ----------- .../src/rosenbrock_tableaus.jl | 833 ----- .../src/stiff_addsteps.jl | 837 ----- .../test/ode_rosenbrock_tests.jl | 706 ---- lib/OrdinaryDiffEqRosenbrock/test/runtests.jl | 3 - lib/OrdinaryDiffEqSDIRK/Project.toml | 22 - .../src/OrdinaryDiffEqSDIRK.jl | 2 - lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl | 47 - lib/OrdinaryDiffEqSDIRK/src/algorithms.jl | 864 ----- .../src/kencarp_kvaerno_caches.jl | 642 ---- .../src/kencarp_kvaerno_perform_step.jl | 2665 -------------- lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl | 998 ------ .../src/sdirk_perform_step.jl | 3154 ----------------- lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl | 2776 --------------- 71 files changed, 36358 deletions(-) delete mode 100644 lib/OrdinaryDiffEqBDF/Project.toml delete mode 100644 lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl delete mode 100644 lib/OrdinaryDiffEqBDF/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqBDF/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqBDF/src/bdf_caches.jl delete mode 100644 lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqExplicitRK/Project.toml delete mode 100644 lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl delete mode 100644 lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl delete mode 100644 lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/Project.toml delete mode 100644 lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/src/controllers.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/src/firk_caches.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl delete mode 100644 lib/OrdinaryDiffEqFIRK/test/runtests.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/Project.toml delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryHighOrderRK.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_addsteps.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_caches.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_tableaus.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/interp_func.jl delete mode 100644 lib/OrdinaryDiffEqHighOrderRK/src/interpolants.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/Project.toml delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/fixed_timestep_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/interp_func.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/interpolants.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_addsteps.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_caches.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_tableaus.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/src/split_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/test/owrenzen_tests.jl delete mode 100644 lib/OrdinaryDiffEqLowOrderRK/test/runtests.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/Project.toml delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl delete mode 100644 lib/OrdinaryDiffEqRosenbrock/test/runtests.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/Project.toml delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/algorithms.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl delete mode 100644 lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml deleted file mode 100644 index cd2e47a403..0000000000 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ /dev/null @@ -1,22 +0,0 @@ -name = "OrdinaryDiffEqBDF" -uuid = "34d55129-80d4-4dd1-bb14-71372a5ab94f" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" - -[compat] -julia = "1.10" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl deleted file mode 100644 index 9d4a0e02cd..0000000000 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ /dev/null @@ -1,25 +0,0 @@ -module OrdinaryDiffEqBDF - -import OrdinaryDiffEq: alg_order, calculate_residuals!, - initialize!, perform_step!, @unpack, unwrap_alg, - calculate_residuals, alg_extrapolates, - OrdinaryDiffEqAlgorithm, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqAdaptivePartitionedAlgorithm, - OrdinaryDiffEqPartitionedAlgorithm, - OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, - alg_cache, _vec, _reshape, @cache, isfsal, full_cache, - constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools -using DiffEqBase: @def, @tight_loop_macros - - -include("algorithms.jl") -include("alg_utils.jl") -include("bdf_caches.jl") -include("bdf_perform_step.jl") - -export SBDF, ABDF2, QNDF1, QNDF2, QNDF, MEBDF2 - -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl deleted file mode 100644 index 1a7a3cc73c..0000000000 --- a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl +++ /dev/null @@ -1,23 +0,0 @@ -alg_extrapolates(alg::ABDF2) = true -alg_extrapolates(alg::SBDF) = true -alg_extrapolates(alg::MEBDF2) = true - -alg_order(alg::ABDF2) = 2 -alg_order(alg::SBDF) = alg.order -alg_order(alg::QNDF1) = 1 -alg_order(alg::MEBDF2) = 2 -alg_order(alg::FBDF) = 1 #dummy value -alg_order(alg::QNDF2) = 2 -alg_order(alg::QNDF) = 1 #dummy value - -get_current_alg_order(alg::QNDF, cache) = cache.order -get_current_alg_order(alg::FBDF, cache) = cache.order - -get_current_adaptive_order(alg::FBDF, cache) = cache.order - -qsteady_max_default(alg::QNDF) = 2 // 1 -qsteady_max_default(alg::QNDF2) = 2 // 1 -qsteady_max_default(alg::QNDF1) = 2 // 1 - -qsteady_min_default(alg::FBDF) = 9 // 10 -qsteady_max_default(alg::FBDF) = 2 // 1 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl deleted file mode 100644 index 0481ca06e0..0000000000 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ /dev/null @@ -1,223 +0,0 @@ -""" -Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. Implicit-Explicit Methods for Time- -Dependent Partial Differential Equations. 1995 Society for Industrial and Applied Mathematics -Journal on Numerical Analysis, 32(3), pp 797-823, 1995. doi: https://doi.org/10.1137/0732037 -""" -struct SBDF{CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - order::Int - ark::Bool -end - -function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, ark = false) - SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(linsolve, - nlsolve, - precs, - κ, - tol, - extrapolant, - order, - ark) -end - -# All keyword form needed for remake -function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, - order, ark = false) - SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(linsolve, - nlsolve, - precs, - κ, - tol, - extrapolant, - order, - ark) -end - -""" -E. Alberdi Celayaa, J. J. Anza Aguirrezabalab, P. Chatzipantelidisc. Implementation of -an Adaptive BDF2 Formula and Comparison with The MATLAB Ode15s. Procedia Computer Science, -29, pp 1014-1026, 2014. doi: https://doi.org/10.1016/j.procs.2014.05.091 - -ABDF2: Multistep Method -An adaptive order 2 L-stable fixed leading coefficient multistep BDF method. -""" -struct ABDF2{CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function ABDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - κ = nothing, tol = nothing, linsolve = nothing, precs = DEFAULT_PRECS, - nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :Standard, step_limiter! = trivial_limiter!) - ABDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(step_limiter!)}(linsolve, nlsolve, precs, κ, tol, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -QNDF1: Multistep Method -An adaptive order 1 quasi-constant timestep L-stable numerical differentiation function (NDF) method. -Optional parameter kappa defaults to Shampine's accuracy-optimal -0.1850. - -See also `QNDF`. -""" -struct QNDF1{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, kappa = -0.1850, - controller = :Standard, step_limiter! = trivial_limiter!) - QNDF1{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(kappa), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - kappa, - controller, - step_limiter!) -end - -""" -QNDF2: Multistep Method -An adaptive order 2 quasi-constant timestep L-stable numerical differentiation function (NDF) method. - -See also `QNDF`. -""" -struct QNDF2{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, kappa = -1 // 9, - controller = :Standard, step_limiter! = trivial_limiter!) - QNDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(kappa), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - kappa, - controller, - step_limiter!) -end - -""" -QNDF: Multistep Method -An adaptive order quasi-constant timestep NDF method. -Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). - -@article{shampine1997matlab, -title={The matlab ode suite}, -author={Shampine, Lawrence F and Reichelt, Mark W}, -journal={SIAM journal on scientific computing}, -volume={18}, -number={1}, -pages={1--22}, -year={1997}, -publisher={SIAM} -} -""" -struct QNDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, kappa = promote(-0.1850, -1 // 9, -0.0823, -0.0415, 0), - controller = :Standard, step_limiter! = trivial_limiter!) where {MO} - QNDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(kappa), typeof(step_limiter!)}( - max_order, linsolve, nlsolve, precs, κ, tol, - extrapolant, kappa, controller, step_limiter!) -end - -""" -MEBDF2: Multistep Method -The second order Modified Extended BDF method, which has improved stability properties over the standard BDF. -Fixed timestep only. -""" -struct MEBDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function MEBDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant) - MEBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl b/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl deleted file mode 100644 index 78a64c7c7b..0000000000 --- a/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl +++ /dev/null @@ -1,658 +0,0 @@ -@cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: - OrdinaryDiffEqConstantCache - nlsolver::N - eulercache::ImplicitEulerConstantCache - dtₙ₋₁::dtType - fsalfirstprev::rate_prototype -end - -function alg_cache(alg::ABDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 2 // 3, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - eulercache = ImplicitEulerConstantCache(nlsolver) - - dtₙ₋₁ = one(dt) - fsalfirstprev = rate_prototype - - ABDF2ConstantCache(nlsolver, eulercache, dtₙ₋₁, fsalfirstprev) -end - -@cache mutable struct ABDF2Cache{uType, rateType, uNoUnitsType, N, dtType, StepLimiter} <: - OrdinaryDiffEqMutableCache - uₙ::uType - uₙ₋₁::uType - uₙ₋₂::uType - fsalfirst::rateType - fsalfirstprev::rateType - zₙ₋₁::uType - atmp::uNoUnitsType - nlsolver::N - eulercache::ImplicitEulerCache - dtₙ₋₁::dtType - step_limiter!::StepLimiter -end - -function alg_cache(alg::ABDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 2 // 3, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - fsalfirstprev = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - algebraic_vars = f.mass_matrix === I ? nothing : - [all(iszero, x) for x in eachcol(f.mass_matrix)] - - eulercache = ImplicitEulerCache( - u, uprev, uprev2, fsalfirst, atmp, nlsolver, algebraic_vars, alg.step_limiter!) - - dtₙ₋₁ = one(dt) - zₙ₋₁ = zero(u) - - ABDF2Cache(u, uprev, uprev2, fsalfirst, fsalfirstprev, zₙ₋₁, atmp, - nlsolver, eulercache, dtₙ₋₁, alg.step_limiter!) -end - -# SBDF - -@cache mutable struct SBDFConstantCache{rateType, N, uType} <: OrdinaryDiffEqConstantCache - cnt::Int - ark::Bool - k2::rateType - nlsolver::N - uprev2::uType - uprev4::uType - uprev3::uType - k₁::rateType - k₂::rateType - k₃::rateType - du₁::rateType - du₂::rateType -end - -@cache mutable struct SBDFCache{uType, rateType, N} <: OrdinaryDiffEqMutableCache - cnt::Int - ark::Bool - u::uType - uprev::uType - fsalfirst::rateType - nlsolver::N - uprev2::uType - uprev3::uType - uprev4::uType - k₁::rateType - k₂::rateType - k₃::rateType - du₁::rateType - du₂::rateType -end - -function alg_cache(alg::SBDF, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - k2 = rate_prototype - k₁ = rate_prototype - k₂ = rate_prototype - k₃ = rate_prototype - du₁ = rate_prototype - du₂ = rate_prototype - - uprev2 = u - uprev3 = u - uprev4 = u - - SBDFConstantCache(1, alg.ark, k2, nlsolver, uprev2, uprev3, uprev4, k₁, k₂, k₃, du₁, - du₂) -end - -function alg_cache(alg::SBDF, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - order = alg.order - - k₁ = zero(rate_prototype) - k₂ = order >= 3 ? zero(rate_prototype) : k₁ - k₃ = order == 4 ? zero(rate_prototype) : k₁ - du₁ = zero(rate_prototype) - du₂ = zero(rate_prototype) - - uprev2 = zero(u) - uprev3 = order >= 3 ? zero(u) : uprev2 - uprev4 = order == 4 ? zero(u) : uprev2 - - SBDFCache( - 1, alg.ark, u, uprev, fsalfirst, nlsolver, uprev2, uprev3, uprev4, k₁, k₂, k₃, - du₁, du₂) -end - -# QNDF1 - -@cache mutable struct QNDF1ConstantCache{ - N, - coefType, - coefType1, - coefType2, - dtType, - uType -} <: OrdinaryDiffEqConstantCache - nlsolver::N - D::coefType1 - D2::coefType2 - R::coefType - U::coefType - uprev2::uType - dtₙ₋₁::dtType -end - -@cache mutable struct QNDF1Cache{uType, rateType, coefType, coefType1, coefType2, - uNoUnitsType, N, dtType, StepLimiter} <: OrdinaryDiffEqMutableCache - uprev2::uType - fsalfirst::rateType - D::coefType1 - D2::coefType2 - R::coefType - U::coefType - atmp::uNoUnitsType - utilde::uType - nlsolver::N - dtₙ₋₁::dtType - step_limiter!::StepLimiter -end - -function alg_cache(alg::QNDF1, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = zero(inv((1 - alg.kappa))), 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - uprev2 = u - dtₙ₋₁ = zero(t) - - D = fill(zero(u), 1, 1) - D2 = fill(zero(u), 1, 2) - R = fill(zero(t), 1, 1) - U = fill(zero(t), 1, 1) - - U!(1, U) - - QNDF1ConstantCache(nlsolver, D, D2, R, U, uprev2, dtₙ₋₁) -end - -function alg_cache(alg::QNDF1, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = zero(inv((1 - alg.kappa))), 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - D = Array{typeof(u)}(undef, 1, 1) - D2 = Array{typeof(u)}(undef, 1, 2) - - R = fill(zero(t), 1, 1) - U = fill(zero(t), 1, 1) - - D[1] = zero(u) - D2[1] = zero(u) - D2[2] = zero(u) - - U!(1, U) - - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - utilde = zero(u) - uprev2 = zero(u) - dtₙ₋₁ = zero(dt) - - QNDF1Cache( - uprev2, fsalfirst, D, D2, R, U, atmp, utilde, nlsolver, dtₙ₋₁, alg.step_limiter!) -end - -# QNDF2 - -@cache mutable struct QNDF2ConstantCache{ - N, - coefType, - coefType1, - coefType2, - uType, - dtType -} <: OrdinaryDiffEqConstantCache - nlsolver::N - D::coefType1 - D2::coefType2 - R::coefType - U::coefType - uprev2::uType - uprev3::uType - dtₙ₋₁::dtType - dtₙ₋₂::dtType -end - -@cache mutable struct QNDF2Cache{uType, rateType, coefType, coefType1, coefType2, - uNoUnitsType, N, dtType, StepLimiter} <: OrdinaryDiffEqMutableCache - uprev2::uType - uprev3::uType - fsalfirst::rateType - D::coefType1 - D2::coefType2 - R::coefType - U::coefType - atmp::uNoUnitsType - utilde::uType - nlsolver::N - dtₙ₋₁::dtType - dtₙ₋₂::dtType - step_limiter!::StepLimiter -end - -function alg_cache(alg::QNDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = zero(inv((1 - alg.kappa))), 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - uprev2 = u - uprev3 = u - dtₙ₋₁ = zero(t) - dtₙ₋₂ = zero(t) - - D = fill(zero(u), 1, 2) - D2 = fill(zero(u), 1, 3) - R = fill(zero(t), 2, 2) - U = fill(zero(t), 2, 2) - - U!(2, U) - - QNDF2ConstantCache(nlsolver, D, D2, R, U, uprev2, uprev3, dtₙ₋₁, dtₙ₋₂) -end - -function alg_cache(alg::QNDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = zero(inv((1 - alg.kappa))), 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - D = Array{typeof(u)}(undef, 1, 2) - D2 = Array{typeof(u)}(undef, 1, 3) - R = fill(zero(t), 2, 2) - U = fill(zero(t), 2, 2) - - D[1] = zero(u) - D[2] = zero(u) - D2[1] = zero(u) - D2[2] = zero(u) - D2[3] = zero(u) - - U!(2, U) - - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - utilde = zero(u) - uprev2 = zero(u) - uprev3 = zero(u) - dtₙ₋₁ = zero(dt) - dtₙ₋₂ = zero(dt) - - QNDF2Cache(uprev2, uprev3, fsalfirst, D, D2, R, U, atmp, - utilde, nlsolver, dtₙ₋₁, dtₙ₋₂, alg.step_limiter!) -end - -@cache mutable struct QNDFConstantCache{ - MO, - N, - coefType, - UType, - dtType, - EEstType, - gammaType -} <: OrdinaryDiffEqConstantCache - nlsolver::N - U::UType - D::coefType - prevD::coefType - prevorder::Int - order::Int - max_order::Val{MO} - dtprev::dtType - nconsteps::Int ##Successful Consecutive Step with the same step size - consfailcnt::Int #Consecutive failed steps count - EEst1::EEstType #Error Estimator for k-1 order - EEst2::EEstType #Error Estimator for k+1 order - γₖ::gammaType -end - -function alg_cache(alg::QNDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits -} where {MO} - max_order = MO - γ, c = one(eltype(alg.kappa)), 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - dtprev = one(dt) - D = Matrix{uEltypeNoUnits}(undef, length(u), max_order + 2) - recursivefill!(D, zero(uEltypeNoUnits)) - prevD = similar(D) - recursivefill!(prevD, zero(uEltypeNoUnits)) - EEst1 = tTypeNoUnits(1) - EEst2 = tTypeNoUnits(1) - - U = zero(MMatrix{max_order, max_order, tTypeNoUnits}) - for r in 1:max_order - U[1, r] = -r - for j in 2:max_order - U[j, r] = U[j - 1, r] * ((j - 1) - r) / j - end - end - U = SArray(U) - - γₖ = SVector(ntuple(k -> sum(tTypeNoUnits(1 // j) for j in 1:k), Val(max_order))) - - QNDFConstantCache(nlsolver, U, D, prevD, 1, 1, Val(max_order), dtprev, 0, 0, EEst1, - EEst2, γₖ) -end - -@cache mutable struct QNDFCache{MO, UType, RUType, rateType, N, coefType, dtType, EEstType, - gammaType, uType, uNoUnitsType, StepLimiter} <: - OrdinaryDiffEqMutableCache - fsalfirst::rateType - dd::uType - utilde::uType - utildem1::uType - utildep1::uType - ϕ::uType - u₀::uType - nlsolver::N - U::UType - RU::RUType - D::coefType - Dtmp::coefType - tmp2::uType - prevD::coefType - order::Int - prevorder::Int - max_order::Val{MO} - dtprev::dtType - nconsteps::Int ##Successful consecutive step with the same step size - consfailcnt::Int #Consecutive failed steps count - EEst1::EEstType #Error Estimator for k-1 order - EEst2::EEstType #Error Estimator for k+1 order - γₖ::gammaType - atmp::uNoUnitsType - atmpm1::uNoUnitsType - atmpp1::uNoUnitsType - step_limiter!::StepLimiter -end - -TruncatedStacktraces.@truncate_stacktrace QNDFCache 1 - -function alg_cache(alg::QNDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits -} where {MO} - max_order = MO - γ, c = one(eltype(alg.kappa)), 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - dd = zero(u) - utilde = zero(u) - utildem1 = zero(u) - utildep1 = zero(u) - ϕ = zero(u) - u₀ = zero(u) - dtprev = one(dt) - D = similar(u, uEltypeNoUnits, length(u), max_order + 2) - recursivefill!(D, zero(uEltypeNoUnits)) - Dtmp = similar(D) - recursivefill!(Dtmp, zero(uEltypeNoUnits)) - prevD = zero(similar(D)) - atmp = zero(similar(u, uEltypeNoUnits)) - atmpm1 = zero(similar(u, uEltypeNoUnits)) - atmpp1 = zero(similar(u, uEltypeNoUnits)) - tmp2 = zero(u) - EEst1 = tTypeNoUnits(1) - EEst2 = tTypeNoUnits(1) - - U = zero(MMatrix{max_order, max_order, tTypeNoUnits}) - for r in 1:max_order - U[1, r] = -r - for j in 2:max_order - U[j, r] = U[j - 1, r] * ((j - 1) - r) / j - end - end - U = SArray(U) - - RU = Matrix(U) - γₖ = SVector(ntuple(k -> sum(tTypeNoUnits(1 // j) for j in 1:k), Val(max_order))) - - QNDFCache(fsalfirst, dd, utilde, utildem1, utildep1, ϕ, u₀, nlsolver, U, RU, D, Dtmp, - tmp2, prevD, 1, 1, Val(max_order), dtprev, 0, 0, EEst1, EEst2, γₖ, atmp, - atmpm1, atmpp1, alg.step_limiter!) -end - -@cache mutable struct MEBDF2Cache{uType, rateType, uNoUnitsType, N} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - uprev2::uType - fsalfirst::rateType - z₁::uType - z₂::uType - tmp2::uType - atmp::uNoUnitsType - nlsolver::N -end - -function alg_cache(alg::MEBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - tmp2 = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - MEBDF2Cache(u, uprev, uprev2, fsalfirst, z₁, z₂, tmp2, atmp, nlsolver) -end - -mutable struct MEBDF2ConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - -function alg_cache(alg::MEBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - MEBDF2ConstantCache(nlsolver) -end - -@cache mutable struct FBDFConstantCache{MO, N, tsType, tType, uType, uuType, coeffType, - EEstType, rType, wType} <: - OrdinaryDiffEqConstantCache - nlsolver::N - ts::tsType - ts_tmp::tsType - t_old::tType - u_history::uuType - order::Int - prev_order::Int - u_corrector::uType - bdf_coeffs::coeffType - max_order::Val{MO} - nconsteps::Int # consecutive success steps - consfailcnt::Int #consecutive failed step counts - terkm2::EEstType - terkm1::EEstType - terk::EEstType - terkp1::EEstType - r::rType - weights::wType - iters_from_event::Int -end - -function alg_cache(alg::FBDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits -} where {MO} - γ, c = 1.0, 1.0 - max_order = MO - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - bdf_coeffs = SA[1 -1 0 0 0 0; - 3//2 -2 1//2 0 0 0; - 11//6 -3 3//2 -1//3 0 0; - 25//12 -4 3 -4//3 1//4 0; - 137//60 -5 5 -10//3 5//4 -1//5] - ts = zero(Vector{typeof(t)}(undef, max_order + 2)) #ts is the successful past points, it will be updated after successful step - ts_tmp = similar(ts) - - u_history = zero(Matrix{eltype(u)}(undef, length(u), max_order + 2)) - order = 1 - prev_order = 1 - u_corrector = similar(u_history) - recursivefill!(u_corrector, zero(eltype(u))) - recursivefill!(u_history, zero(eltype(u_history))) - terkm2 = tTypeNoUnits(1) - terkm1 = tTypeNoUnits(1) - terk = tTypeNoUnits(1) - terkp1 = tTypeNoUnits(1) - r = zero(Vector{typeof(t)}(undef, max_order + 2)) - weights = zero(Vector{typeof(t)}(undef, max_order + 2)) - weights[1] = 1 - nconsteps = 0 - consfailcnt = 0 - t_old = zero(t) - iters_from_event = 0 - - FBDFConstantCache(nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, - u_corrector, bdf_coeffs, Val(5), nconsteps, consfailcnt, terkm2, - terkm1, terk, terkp1, r, weights, iters_from_event) -end - -@cache mutable struct FBDFCache{ - MO, N, rateType, uNoUnitsType, tsType, tType, uType, uuType, - coeffType, EEstType, rType, wType, StepLimiter} <: - OrdinaryDiffEqMutableCache - fsalfirst::rateType - nlsolver::N - ts::tsType - ts_tmp::tsType - t_old::tType - u_history::uuType - order::Int - prev_order::Int - u_corrector::uuType - u₀::uType - bdf_coeffs::coeffType - max_order::Val{MO} - nconsteps::Int # consecutive success steps - consfailcnt::Int #consecutive failed step counts - tmp::uType - atmp::uNoUnitsType - terkm2::EEstType - terkm1::EEstType - terk::EEstType #terk corresponds to hᵏyᵏ(tₙ₊₁) - terkp1::EEstType - terk_tmp::uType - terkp1_tmp::uType - r::rType - weights::wType #weights of Lagrangian formula - equi_ts::tsType - iters_from_event::Int - step_limiter!::StepLimiter -end - -TruncatedStacktraces.@truncate_stacktrace FBDFCache 1 - -function alg_cache(alg::FBDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {MO, uEltypeNoUnits, uBottomEltypeNoUnits, - tTypeNoUnits} - γ, c = 1.0, 1.0 - fsalfirst = zero(rate_prototype) - max_order = MO - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - bdf_coeffs = SA[1 -1 0 0 0 0; - 3//2 -2 1//2 0 0 0; - 11//6 -3 3//2 -1//3 0 0; - 25//12 -4 3 -4//3 1//4 0; - 137//60 -5 5 -10//3 5//4 -1//5] - ts = Vector{typeof(t)}(undef, max_order + 2) #ts is the successful past points, it will be updated after successful step - u_history = Matrix{eltype(u)}(undef, length(u), max_order + 2) - order = 1 - prev_order = 1 - u_corrector = similar(u_history) - recursivefill!(ts, zero(t)) - recursivefill!(u_corrector, zero(eltype(u))) - recursivefill!(u_history, zero(eltype(u_history))) - terkm2 = tTypeNoUnits(1) - terkm1 = tTypeNoUnits(1) - terk = tTypeNoUnits(1) - terkp1 = tTypeNoUnits(1) - terk_tmp = similar(u) - terkp1_tmp = similar(u) - r = Vector{typeof(t)}(undef, max_order + 2) - weights = Vector{typeof(t)}(undef, max_order + 2) - recursivefill!(r, zero(t)) - recursivefill!(weights, zero(t)) - weights[1] = 1 - nconsteps = 0 - consfailcnt = 0 - t_old = zero(t) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, zero(uEltypeNoUnits)) - u₀ = similar(u) - equi_ts = similar(ts) - tmp = similar(u) - ts_tmp = similar(ts) - iters_from_event = 0 - - FBDFCache(fsalfirst, nlsolver, ts, ts_tmp, t_old, u_history, order, prev_order, - u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, - terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, - iters_from_event, alg.step_limiter!) -end diff --git a/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl b/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl deleted file mode 100644 index 082d4faa03..0000000000 --- a/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl +++ /dev/null @@ -1,1345 +0,0 @@ -function initialize!(integrator, cache::ABDF2ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::ABDF2ConstantCache, repeat_step = false) - @unpack t, f, p = integrator - @unpack dtₙ₋₁, nlsolver = cache - alg = unwrap_alg(integrator, true) - dtₙ, uₙ, uₙ₋₁, uₙ₋₂ = integrator.dt, integrator.u, integrator.uprev, integrator.uprev2 - - # TODO: this doesn't look right - if integrator.iter == 1 && !integrator.u_modified - cache.dtₙ₋₁ = dtₙ - cache.eulercache.nlsolver.method = DIRK - perform_step!(integrator, cache.eulercache, repeat_step) - cache.fsalfirstprev = integrator.fsalfirst - return - end - - fₙ₋₁ = integrator.fsalfirst - ρ = dtₙ / dtₙ₋₁ - β₀ = 2 // 3 - β₁ = -(ρ - 1) / 3 - α₀ = 1 - α̂ = ρ^2 / 3 - α₁ = 1 + α̂ - α₂ = -α̂ - - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - u = @.. broadcast=false uₙ₋₁+dtₙ * fₙ₋₁ - else # :constant - u = uₙ₋₁ - end - nlsolver.z = u - - mass_matrix = f.mass_matrix - - if mass_matrix === I - nlsolver.tmp = @.. broadcast=false ((dtₙ * β₁) * fₙ₋₁ + - (α₁ * uₙ₋₁ + α₂ * uₙ₋₂))/(dtₙ * - β₀) - else - _tmp = mass_matrix * @.. broadcast=false (α₁ * uₙ₋₁+α₂ * uₙ₋₂) - nlsolver.tmp = @.. broadcast=false ((dtₙ * β₁) * fₙ₋₁ + _tmp)/(dtₙ * β₀) - end - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - uₙ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - integrator.fsallast = f(uₙ, p, t + dtₙ) - integrator.stats.nf += 1 - - if integrator.opts.adaptive - tmp = integrator.fsallast - (1 + dtₙ / dtₙ₋₁) * integrator.fsalfirst + - (dtₙ / dtₙ₋₁) * cache.fsalfirstprev - est = (dtₙ₋₁ + dtₙ) / 6 * tmp - atmp = calculate_residuals(est, uₙ₋₁, uₙ, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - ################################### Finalize - - if integrator.EEst < one(integrator.EEst) - cache.fsalfirstprev = integrator.fsalfirst - cache.dtₙ₋₁ = dtₙ - end - - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = uₙ - return -end - -function initialize!(integrator, cache::ABDF2Cache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::ABDF2Cache, repeat_step = false) - @unpack t, dt, f, p = integrator - #TODO: remove zₙ₋₁ from the cache - @unpack atmp, dtₙ₋₁, zₙ₋₁, nlsolver, step_limiter! = cache - @unpack z, tmp, ztmp = nlsolver - alg = unwrap_alg(integrator, true) - uₙ, uₙ₋₁, uₙ₋₂, dtₙ = integrator.u, integrator.uprev, integrator.uprev2, integrator.dt - - if integrator.iter == 1 && !integrator.u_modified - cache.dtₙ₋₁ = dtₙ - cache.eulercache.nlsolver.method = DIRK - perform_step!(integrator, cache.eulercache, repeat_step) - cache.fsalfirstprev .= integrator.fsalfirst - nlsolver.tmp = tmp - return - end - - fₙ₋₁ = integrator.fsalfirst - ρ = dtₙ / dtₙ₋₁ - β₀ = 2 // 3 - β₁ = -(ρ - 1) / 3 - α₀ = 1 - α̂ = ρ^2 / 3 - α₁ = 1 + α̂ - α₂ = -α̂ - - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - @.. broadcast=false z=uₙ₋₁ + dtₙ * fₙ₋₁ - else # :constant - @.. broadcast=false z=uₙ₋₁ - end - - mass_matrix = f.mass_matrix - - if mass_matrix === I - @.. broadcast=false tmp=((dtₙ * β₁) * fₙ₋₁ + (α₁ * uₙ₋₁ + α₂ * uₙ₋₂)) / (dtₙ * β₀) - else - dz = nlsolver.cache.dz - @.. broadcast=false dz=α₁ * uₙ₋₁ + α₂ * uₙ₋₂ - mul!(ztmp, mass_matrix, dz) - @.. broadcast=false tmp=((dtₙ * β₁) * fₙ₋₁ + ztmp) / (dtₙ * β₀) - end - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false uₙ=z - - step_limiter!(uₙ, integrator, p, t + dtₙ) - - f(integrator.fsallast, uₙ, p, t + dtₙ) - integrator.stats.nf += 1 - if integrator.opts.adaptive - btilde0 = (dtₙ₋₁ + dtₙ) * 1 // 6 - btilde1 = 1 + dtₙ / dtₙ₋₁ - btilde2 = dtₙ / dtₙ₋₁ - @.. broadcast=false tmp=btilde0 * - (integrator.fsallast - btilde1 * integrator.fsalfirst + - btilde2 * cache.fsalfirstprev) - calculate_residuals!(atmp, tmp, uₙ₋₁, uₙ, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - ################################### Finalize - - if integrator.EEst < one(integrator.EEst) - @.. broadcast=false cache.fsalfirstprev=integrator.fsalfirst - cache.dtₙ₋₁ = dtₙ - end - return -end - -# SBDF - -function initialize!(integrator, cache::SBDFConstantCache) - @unpack uprev, p, t = integrator - @unpack f1, f2 = integrator.f - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - cache.du₁ = f1(uprev, p, t) - cache.du₂ = f2(uprev, p, t) - integrator.stats.nf += 1 - integrator.stats.nf2 += 1 - integrator.fsalfirst = cache.du₁ + cache.du₂ - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::SBDFConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - alg = unwrap_alg(integrator, true) - @unpack uprev2, uprev3, uprev4, du₁, du₂, k₁, k₂, k₃, nlsolver = cache - @unpack f1, f2 = integrator.f - cnt = cache.cnt = min(alg.order, integrator.iter + 1) - integrator.iter == 1 && !integrator.u_modified && (cnt = cache.cnt = 1) - nlsolver.γ = γ = inv(γₖ[cnt]) - if cache.ark - # Additive Runge-Kutta Method - du₂ = f2(uprev + dt * du₁, p, t) - integrator.stats.nf2 += 1 - end - if cnt == 1 - tmp = uprev + dt * du₂ - elseif cnt == 2 - tmp = γ * (2 * uprev - 1 // 2 * uprev2 + dt * (2 * du₂ - k₁)) - elseif cnt == 3 - tmp = γ * - (3 * uprev - 3 // 2 * uprev2 + 1 // 3 * uprev3 + dt * (3 * (du₂ - k₁) + k₂)) - else - tmp = γ * (4 * uprev - 3 * uprev2 + 4 // 3 * uprev3 - 1 // 4 * uprev4 + - dt * (4 * du₂ - 6 * k₁ + 4 * k₂ - k₃)) - end - nlsolver.tmp = tmp - - # Implicit part - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - z = dt * du₁ - else # :constant - z = zero(u) - end - nlsolver.z = z - - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = nlsolver.tmp + γ * z - - cnt == 4 && (cache.uprev4 = uprev3; - cache.k₃ = k₂) - cnt >= 3 && (cache.uprev3 = uprev2; - cache.k₂ = k₁) - (cache.uprev2 = uprev; - cache.k₁ = du₂) - cache.du₁ = f1(u, p, t + dt) - cache.du₂ = f2(u, p, t + dt) - integrator.stats.nf += 1 - integrator.stats.nf2 += 1 - integrator.fsallast = cache.du₁ + cache.du₂ - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::SBDFCache) - @unpack uprev, p, t = integrator - @unpack f1, f2 = integrator.f - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - f1(cache.du₁, uprev, p, t) - f2(cache.du₂, uprev, p, t) - integrator.stats.nf += 1 - integrator.stats.nf2 += 1 - @.. broadcast=false integrator.fsalfirst=cache.du₁ + cache.du₂ -end - -function perform_step!(integrator, cache::SBDFCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - alg = unwrap_alg(integrator, true) - @unpack uprev2, uprev3, uprev4, k₁, k₂, k₃, du₁, du₂, nlsolver = cache - @unpack tmp, z = nlsolver - @unpack f1, f2 = integrator.f - cnt = cache.cnt = min(alg.order, integrator.iter + 1) - integrator.iter == 1 && !integrator.u_modified && (cnt = cache.cnt = 1) - nlsolver.γ = γ = inv(γₖ[cnt]) - # Explicit part - if cache.ark - # Additive Runge-Kutta Method - f2(du₂, uprev + dt * du₁, p, t) - integrator.stats.nf2 += 1 - end - if cnt == 1 - @.. broadcast=false tmp=uprev + dt * du₂ - elseif cnt == 2 - @.. broadcast=false tmp=γ * (2 * uprev - 1 // 2 * uprev2 + dt * (2 * du₂ - k₁)) - elseif cnt == 3 - @.. broadcast=false tmp=γ * (3 * uprev - 3 // 2 * uprev2 + 1 // 3 * uprev3 + - dt * (3 * (du₂ - k₁) + k₂)) - else - @.. broadcast=false tmp=γ * (4 * uprev - 3 * uprev2 + 4 // 3 * uprev3 - - 1 // 4 * uprev4 + dt * (4 * du₂ - 6 * k₁ + 4 * k₂ - k₃)) - end - # Implicit part - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - @.. broadcast=false z=dt * du₁ - else # :constant - @.. broadcast=false z=zero(eltype(u)) - end - - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=tmp + γ * z - - cnt == 4 && (cache.uprev4 .= uprev3; - cache.k₃ .= k₂) - cnt >= 3 && (cache.uprev3 .= uprev2; - cache.k₂ .= k₁) - (cache.uprev2 .= uprev; - cache.k₁ .= du₂) - f1(du₁, u, p, t + dt) - f2(du₂, u, p, t + dt) - integrator.stats.nf += 1 - integrator.stats.nf2 += 1 - @.. broadcast=false integrator.fsallast=du₁ + du₂ -end - -# QNDF1 - -function initialize!(integrator, cache::QNDF1ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::QNDF1ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack uprev2, D, D2, R, U, dtₙ₋₁, nlsolver = cache - alg = unwrap_alg(integrator, true) - κ = alg.kappa - cnt = integrator.iter - k = 1 - if cnt > 1 - ρ = dt / dtₙ₋₁ - D[1] = uprev - uprev2 # backward diff - if ρ != 1 - R!(k, ρ, cache) - R .= R * U - D[1] = D[1] * R[1, 1] - end - else - κ = zero(alg.kappa) - end - - #Changing uprev2 after D Array has changed with step-size - uprev2 = uprev - D[1] - - β₀ = 1 - α₀ = 1 - κ - α₁ = 1 - 2 * κ - α₂ = κ - - markfirststage!(nlsolver) - - # initial guess - nlsolver.z = uprev + sum(D) - - mass_matrix = f.mass_matrix - - if mass_matrix === I - nlsolver.tmp = @.. broadcast=false (α₁ * uprev + α₂ * uprev2)/(dt * β₀) - else - _tmp = mass_matrix * @.. broadcast=false (α₁ * uprev+α₂ * uprev2) - nlsolver.tmp = @.. broadcast=false _tmp/(dt * β₀) - end - - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - - u = nlsolve!(nlsolver, integrator, cache, repeat_step) - - nlsolvefail(nlsolver) && return - if integrator.opts.adaptive - if integrator.success_iter == 0 - integrator.EEst = one(integrator.EEst) - else - D2[1] = u - uprev - D2[2] = D2[1] - D[1] - utilde = (κ + inv(k + 1)) * D2[2] - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, - t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - end - if integrator.EEst > one(integrator.EEst) - return - end - cache.dtₙ₋₁ = dt - cache.uprev2 = uprev - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -function initialize!(integrator, cache::QNDF1Cache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::QNDF1Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack uprev2, D, D2, R, U, dtₙ₋₁, utilde, atmp, nlsolver, step_limiter! = cache - @unpack z, tmp, ztmp = nlsolver - alg = unwrap_alg(integrator, true) - κ = alg.kappa - cnt = integrator.iter - k = 1 - if cnt > 1 - ρ = dt / dtₙ₋₁ - @.. broadcast=false D[1]=uprev - uprev2 # backward diff - if ρ != 1 - R!(k, ρ, cache) - R .= R * U - @.. broadcast=false D[1]=D[1] * R[1, 1] - end - else - κ = zero(alg.kappa) - end - - #Changing uprev2 after D Array has changed with step-size - uprev2 = uprev - D[1] - - β₀ = 1 - α₀ = 1 - κ - α₁ = 1 - 2 * κ - α₂ = κ - - markfirststage!(nlsolver) - - # initial guess - nlsolver.z = uprev + sum(D) - - mass_matrix = f.mass_matrix - - if mass_matrix === I - @.. broadcast=false tmp=(α₁ * uprev + α₂ * uprev2) / (dt * β₀) - else - dz = nlsolver.cache.dz - @.. broadcast=false dz=α₁ * uprev + α₂ * uprev2 - mul!(ztmp, mass_matrix, dz) - @.. broadcast=false tmp=ztmp / (dt * β₀) - end - - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=z - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - if integrator.success_iter == 0 - integrator.EEst = one(integrator.EEst) - else - @.. broadcast=false D2[1]=u - uprev - @.. broadcast=false D2[2]=D2[1] - D[1] - @.. broadcast=false utilde=(κ + inv(k + 1)) * D2[2] - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - end - if integrator.EEst > one(integrator.EEst) - return - end - cache.uprev2 .= uprev - cache.dtₙ₋₁ = dt - f(integrator.fsallast, u, p, t + dt) - integrator.stats.nf += 1 - return -end - -function initialize!(integrator, cache::QNDF2ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::QNDF2ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack uprev2, uprev3, dtₙ₋₁, dtₙ₋₂, D, D2, R, U, nlsolver = cache - alg = unwrap_alg(integrator, true) - cnt = integrator.iter - k = 2 - if cnt == 1 || cnt == 2 - κ = zero(alg.kappa) - γ₁ = 1 // 1 - γ₂ = 1 // 1 - elseif dtₙ₋₁ != dtₙ₋₂ - κ = alg.kappa - γ₁ = 1 // 1 - γ₂ = 1 // 1 + 1 // 2 - ρ₁ = dt / dtₙ₋₁ - ρ₂ = dt / dtₙ₋₂ - D[1] = uprev - uprev2 - D[1] = D[1] * ρ₁ - D[2] = D[1] - ((uprev2 - uprev3) * ρ₂) - else - κ = alg.kappa - γ₁ = 1 // 1 - γ₂ = 1 // 1 + 1 // 2 - ρ = dt / dtₙ₋₁ - # backward diff - D[1] = uprev - uprev2 - D[2] = D[1] - (uprev2 - uprev3) - if ρ != 1 - R!(k, ρ, cache) - R .= R * U - D[1] = D[1] * R[1, 1] + D[2] * R[2, 1] - D[2] = D[1] * R[1, 2] + D[2] * R[2, 2] - end - end - - β₀ = inv((1 - κ) * γ₂) - α₀ = 1 - - u₀ = uprev + D[1] + D[2] - ϕ = (γ₁ * D[1] + γ₂ * D[2]) * β₀ - - markfirststage!(nlsolver) - - # initial guess - nlsolver.z = uprev + sum(D) - - mass_matrix = f.mass_matrix - - if mass_matrix === I - nlsolver.tmp = @.. broadcast=false (u₀ - ϕ)/(dt * β₀) - else - _tmp = mass_matrix * @.. broadcast=false (u₀-ϕ) - nlsolver.tmp = @.. broadcast=false _tmp/(dt * β₀) - end - - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - - u = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - if integrator.opts.adaptive - if integrator.success_iter == 0 - integrator.EEst = one(integrator.EEst) - elseif integrator.success_iter == 1 - utilde = (u - uprev) - ((uprev - uprev2) * dt / dtₙ₋₁) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, - t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - D2[1] = u - uprev - D2[2] = D2[1] - D[1] - D2[3] = D2[2] - D[2] - utilde = (κ * γ₂ + inv(k + 1)) * D2[3] - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, - t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - end - if integrator.EEst > one(integrator.EEst) - return - end - - cache.uprev3 = uprev2 - cache.uprev2 = uprev - cache.dtₙ₋₂ = dtₙ₋₁ - cache.dtₙ₋₁ = dt - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -function initialize!(integrator, cache::QNDF2Cache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::QNDF2Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack uprev2, uprev3, dtₙ₋₁, dtₙ₋₂, D, D2, R, U, utilde, atmp, nlsolver, step_limiter! = cache - @unpack z, tmp, ztmp = nlsolver - alg = unwrap_alg(integrator, true) - cnt = integrator.iter - k = 2 - if cnt == 1 || cnt == 2 - κ = zero(alg.kappa) - γ₁ = 1 // 1 - γ₂ = 1 // 1 - elseif dtₙ₋₁ != dtₙ₋₂ - κ = alg.kappa - γ₁ = 1 // 1 - γ₂ = 1 // 1 + 1 // 2 - ρ₁ = dt / dtₙ₋₁ - ρ₂ = dt / dtₙ₋₂ - @.. broadcast=false D[1]=uprev - uprev2 - @.. broadcast=false D[1]=D[1] * ρ₁ - @.. broadcast=false D[2]=D[1] - ((uprev2 - uprev3) * ρ₂) - else - κ = alg.kappa - γ₁ = 1 // 1 - γ₂ = 1 // 1 + 1 // 2 - ρ = dt / dtₙ₋₁ - # backward diff - @.. broadcast=false D[1]=uprev - uprev2 - @.. broadcast=false D[2]=D[1] - (uprev2 - uprev3) - if ρ != 1 - R!(k, ρ, cache) - R .= R * U - @.. broadcast=false D[1]=D[1] * R[1, 1] + D[2] * R[2, 1] - @.. broadcast=false D[2]=D[1] * R[1, 2] + D[2] * R[2, 2] - end - end - - β₀ = inv((1 - κ) * γ₂) - α₀ = 1 - - u₀ = uprev + D[1] + D[2] - ϕ = (γ₁ * D[1] + γ₂ * D[2]) * β₀ - - markfirststage!(nlsolver) - - # initial guess - nlsolver.z = uprev + sum(D) - - mass_matrix = f.mass_matrix - - if mass_matrix === I - @.. broadcast=false tmp=(u₀ - ϕ) / (dt * β₀) - else - dz = nlsolver.cache.dz - @.. broadcast=false dz=u₀ - ϕ - mul!(ztmp, mass_matrix, dz) - @.. broadcast=false tmp=ztmp / (dt * β₀) - end - - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=z - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - if integrator.success_iter == 0 - integrator.EEst = one(integrator.EEst) - elseif integrator.success_iter == 1 - @.. broadcast=false utilde=(u - uprev) - ((uprev - uprev2) * dt / dtₙ₋₁) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - @.. broadcast=false D2[1]=u - uprev - @.. broadcast=false D2[2]=D2[1] - D[1] - @.. broadcast=false D2[3]=D2[2] - D[2] - @.. broadcast=false utilde=(κ * γ₂ + inv(k + 1)) * D2[3] - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - end - if integrator.EEst > one(integrator.EEst) - return - end - - cache.uprev3 .= uprev2 - cache.uprev2 .= uprev - cache.dtₙ₋₂ = dtₙ₋₁ - cache.dtₙ₋₁ = dt - f(integrator.fsallast, u, p, t + dt) - integrator.stats.nf += 1 - return -end - -function initialize!(integrator, cache::QNDFConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::QNDFConstantCache{max_order}, - repeat_step = false) where {max_order} - @unpack t, dt, uprev, u, f, p = integrator - @unpack dtprev, order, D, U, nlsolver, γₖ = cache - alg = unwrap_alg(integrator, true) - - if integrator.u_modified - dtprev = one(dt) - order = 1 - cache.nconsteps = 0 - cache.consfailcnt = 0 - fill!(D, zero(eltype(D))) - fill!(cache.prevD, zero(eltype(D))) - end - - k = order - κlist = alg.kappa - κ = κlist[k] - if cache.consfailcnt > 0 - copyto!(D, cache.prevD) - end - if dt != dtprev || cache.prevorder != k - ρ = dt / dtprev - integrator.cache.nconsteps = 0 - @unpack U = cache - R = calc_R(ρ, k, Val(max_order)) - RU = R * U - Dtmp = D[:, 1:k] * RU[1:k, 1:k] - D[:, 1:k] = Dtmp - end - - α₀ = 1 - β₀ = inv((1 - κ) * γₖ[k]) - if u isa Number - u₀ = sum(D[1:k]) + uprev - ϕ = zero(u) - for i in 1:k - ϕ += γₖ[i] * D[i] - end - else - u₀ = reshape(sum(D[:, 1:k], dims = 2) .+ uprev, size(u)) - ϕ = zero(u) - for i in 1:k - @.. broadcast=false ϕ+=γₖ[i] * D[:, i] - end - end - markfirststage!(nlsolver) - nlsolver.z = u₀ - mass_matrix = f.mass_matrix - - if mass_matrix === I - nlsolver.tmp = @.. broadcast=false (u₀ / β₀ - ϕ)/dt - else - nlsolver.tmp = mass_matrix * @.. broadcast=false (u₀ / β₀ - ϕ)/dt - end - - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = z - dd = u - u₀ - update_D!(D, dd, k) - - if integrator.opts.adaptive - @unpack abstol, reltol, internalnorm = integrator.opts - if cache.consfailcnt > 1 && mass_matrix !== I - # if we get repeated failure and mass_matrix !== I it's likely that - # there's a discontinuity on the algebraic equations - atmp = calculate_residuals(mass_matrix * dd, uprev, u, abstol, reltol, - internalnorm, t) - else - atmp = calculate_residuals(dd, uprev, u, abstol, reltol, internalnorm, t) - end - integrator.EEst = error_constant(integrator, k) * internalnorm(atmp, t) - if k > 1 - @views atmpm1 = calculate_residuals(D[:, k], uprev, u, integrator.opts.abstol, - integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.EEst1 = error_constant(integrator, k - 1) * internalnorm(atmpm1, t) - end - if k < max_order - @views atmpp1 = calculate_residuals(D[:, k + 2], uprev, u, abstol, reltol, - internalnorm, t) - cache.EEst2 = error_constant(integrator, k + 1) * internalnorm(atmpp1, t) - end - end - if integrator.EEst <= one(integrator.EEst) - copyto!(cache.prevD, D) - cache.dtprev = dt - cache.prevorder = k - if integrator.opts.dense - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - end - end - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::QNDFCache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::QNDFCache{max_order}, - repeat_step = false) where {max_order} - @unpack t, dt, uprev, u, f, p = integrator - @unpack dtprev, order, D, nlsolver, γₖ, dd, atmp, atmpm1, atmpp1, utilde, utildem1, utildep1, ϕ, u₀, step_limiter! = cache - alg = unwrap_alg(integrator, true) - - if integrator.u_modified - dtprev = one(dt) - order = 1 - cache.nconsteps = 0 - cache.consfailcnt = 0 - fill!(D, zero(eltype(D))) - fill!(cache.prevD, zero(eltype(D))) - end - - k = order - κlist = alg.kappa - κ = κlist[k] - if cache.consfailcnt > 0 - copyto!(D, cache.prevD) - end - if dt != dtprev || cache.prevorder != k - ρ = dt / dtprev - cache.nconsteps = 0 - @unpack RU, U, Dtmp = cache - R = calc_R(ρ, k, Val(max_order)) - copyto!(RU, R * U) - @views mul!(Dtmp[:, 1:k], D[:, 1:k], RU[1:k, 1:k]) - D, Dtmp = Dtmp, D - cache.D = D - cache.Dtmp = Dtmp - end - - α₀ = 1 - β₀ = inv((1 - κ) * γₖ[k]) - # D[:, j] contains scaled j-th derivative approximation. - # Thus, it’s likely that ||D[:, j+1]|| <= ||D[:, j]|| holds, - # we want to sum small numbers first to minimize the accumulation error. - # Hence, we sum it backwards. - @inbounds for i in 1:length(u₀) - s = D[i, k] - @simd for j in (k - 1):-1:1 - s += D[i, j] - end - u₀[i] = s + uprev[i] - end - @.. broadcast=false ϕ=zero(u) - vecϕ = _vec(ϕ) - for i in 1:k - @views @.. broadcast=false vecϕ+=γₖ[i] * D[:, i] - end - markfirststage!(nlsolver) - @.. broadcast=false nlsolver.z=u₀ - mass_matrix = f.mass_matrix - - if mass_matrix === I - @.. broadcast=false nlsolver.tmp=(u₀ / β₀ - ϕ) / dt - else - @unpack tmp2 = cache - @.. broadcast=false tmp2=(u₀ / β₀ - ϕ) / dt - mul!(nlsolver.tmp, mass_matrix, tmp2) - end - - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=z - @.. broadcast=false dd=u - u₀ - update_D!(D, dd, k) - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - @unpack abstol, reltol, internalnorm = integrator.opts - if cache.consfailcnt > 1 && mass_matrix !== I - # if we get repeated failure and mass_matrix !== I it's likely that - # there's a discontinuity on the algebraic equations - calculate_residuals!(atmp, mul!(nlsolver.tmp, mass_matrix, dd), uprev, u, - abstol, reltol, internalnorm, t) - else - calculate_residuals!(atmp, dd, uprev, u, abstol, reltol, internalnorm, t) - end - integrator.EEst = error_constant(integrator, k) * internalnorm(atmp, t) - if k > 1 - @views calculate_residuals!( - atmpm1, reshape(D[:, k], size(u)), uprev, u, abstol, - reltol, internalnorm, t) - cache.EEst1 = error_constant(integrator, k - 1) * internalnorm(atmpm1, t) - end - if k < max_order - @views calculate_residuals!( - atmpp1, reshape(D[:, k + 2], size(u)), uprev, u, abstol, - reltol, internalnorm, t) - cache.EEst2 = error_constant(integrator, k + 1) * internalnorm(atmpp1, t) - end - end - if integrator.EEst <= one(integrator.EEst) - copyto!(cache.prevD, D) - cache.dtprev = dt - cache.prevorder = k - if integrator.opts.dense - f(integrator.fsallast, u, p, t + dt) - integrator.stats.nf += 1 - end - end - return nothing -end - -### MEBDF2 -function initialize!(integrator, cache::MEBDF2ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::MEBDF2ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - nlsolver.z = dt * integrator.fsalfirst - else # :constant - nlsolver.z = zero(u) - end - - ### STEP 1 - nlsolver.tmp = uprev - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - z₁ = nlsolver.tmp + z - ### STEP 2 - nlsolver.tmp = z₁ - nlsolver.c = 2 - isnewton(nlsolver) && set_new_W!(nlsolver, false) - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - z₂ = z₁ + z - ### STEP 3 - tmp2 = 0.5uprev + z₁ - 0.5z₂ - nlsolver.tmp = tmp2 - nlsolver.c = 1 - isnewton(nlsolver) && set_new_W!(nlsolver, false) - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = tmp2 + z - - ### finalize - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::MEBDF2Cache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::MEBDF2Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, tmp2, nlsolver = cache - z = nlsolver.z - mass_matrix = integrator.f.mass_matrix - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - @.. broadcast=false z=dt * integrator.fsalfirst - else # :constant - z .= zero(eltype(u)) - end - - ### STEP 1 - nlsolver.tmp = uprev - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false z₁=uprev + z - ### STEP 2 - nlsolver.tmp = z₁ - nlsolver.c = 2 - isnewton(nlsolver) && set_new_W!(nlsolver, false) - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false z₂=z₁ + z - ### STEP 3 - # z .= zero(eltype(u)) - @.. broadcast=false tmp2=0.5uprev + z₁ - 0.5z₂ - nlsolver.tmp = tmp2 - nlsolver.c = 1 - isnewton(nlsolver) && set_new_W!(nlsolver, false) - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=tmp2 + z - - ### finalize - f(integrator.fsallast, u, p, t + dt) - integrator.stats.nf += 1 -end - -function initialize!(integrator, cache::FBDFConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::FBDFConstantCache{max_order}, - repeat_step = false) where {max_order} - @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, ts_tmp, iters_from_event, nconsteps = cache - @unpack t, dt, u, f, p, uprev = integrator - - tdt = t + dt - k = order - reinitFBDF!(integrator, cache) - u₀ = zero(u) - if iters_from_event >= 1 - u₀ = calc_Lagrange_interp(k, weights, tdt, ts, u_history, u₀) - else - u₀ = u - end - markfirststage!(nlsolver) - - nlsolver.z = u₀ - mass_matrix = f.mass_matrix - - equi_ts = zeros(k - 1) - for i in 1:(k - 1) - equi_ts[i] = t - dt * i - end - - fill!(u_corrector, zero(eltype(u))) - if u isa Number - for i in 1:(k - 1) - u_corrector[i] = calc_Lagrange_interp(k, weights, equi_ts[i], ts, u_history, - u_corrector[i]) - end - tmp = -uprev * bdf_coeffs[k, 2] - for i in 1:(k - 1) - tmp -= u_corrector[i] * bdf_coeffs[k, i + 2] - end - else - for i in 1:(k - 1) - @.. broadcast=false @views u_corrector[:, i] = $calc_Lagrange_interp( - k, weights, - equi_ts[i], - ts, - u_history, - u_corrector[:, - i]) - end - tmp = -uprev * bdf_coeffs[k, 2] - vc = _vec(tmp) - for i in 1:(k - 1) - @.. broadcast=false @views vc -= u_corrector[:, i] * bdf_coeffs[k, i + 2] - end - end - - if mass_matrix === I - nlsolver.tmp = tmp / dt - else - nlsolver.tmp = mass_matrix * tmp / dt - end - β₀ = inv(bdf_coeffs[k, 1]) - α₀ = 1 #bdf_coeffs[k,1] - nlsolver.γ = β₀ - nlsolver.α = α₀ - - nlsolver.method = COEFFICIENT_MULTISTEP - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = z - - for j in 2:k - r[j] = (1 - j) - for i in 2:(k + 1) - r[j] *= ((tdt - j * dt) - ts[i]) / (i * dt) - end - end - - terkp1 = (u - u₀) - for j in 1:(k + 1) - terkp1 *= j * dt / (tdt - ts[j]) - end - - lte = -1 / (1 + k) - for j in 2:k - lte -= bdf_coeffs[k, j] * r[j] - end - lte *= terkp1 - - if integrator.opts.adaptive - for i in 1:(k + 1) - ts_tmp[i + 1] = ts[i] - end - ts_tmp[1] = tdt - atmp = calculate_residuals(_vec(lte), _vec(uprev), _vec(u), integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - - terk = estimate_terk(integrator, cache, k + 1, Val(max_order), u) - fd_weights = calc_finite_difference_weights(ts_tmp, tdt, k, Val(max_order)) - terk = @.. broadcast=false fd_weights[1, k + 1]*u - if u isa Number - for i in 2:(k + 1) - terk += fd_weights[i, k + 1] * u_history[i - 1] - end - terk *= abs(dt^(k)) - else - vc = _vec(terk) - for i in 2:(k + 1) - @.. broadcast=false @views vc += fd_weights[i, k + 1] * u_history[:, i - 1] - end - terk *= abs(dt^(k)) - end - - atmp = calculate_residuals( - _vec(terk), _vec(uprev), _vec(u), integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - cache.terk = integrator.opts.internalnorm(atmp, t) - - if k > 1 - terkm1 = estimate_terk(integrator, cache, k, Val(max_order), u) - atmp = calculate_residuals(_vec(terkm1), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm1 = integrator.opts.internalnorm(atmp, t) - end - if k > 2 - terkm2 = estimate_terk(integrator, cache, k - 1, Val(max_order), u) - atmp = calculate_residuals(_vec(terkm2), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm2 = integrator.opts.internalnorm(atmp, t) - end - if nconsteps > k + 1 && k < max_order - atmp = calculate_residuals(_vec(terkp1), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkp1 = integrator.opts.internalnorm(atmp, t) - else - cache.terkp1 = zero(cache.terk) - end - end - - integrator.fsallast = f(u, p, tdt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::FBDFCache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::FBDFCache{max_order}, - repeat_step = false) where {max_order} - @unpack ts, u_history, order, u_corrector, bdf_coeffs, r, nlsolver, weights, terk_tmp, terkp1_tmp, atmp, tmp, equi_ts, u₀, ts_tmp, step_limiter! = cache - @unpack t, dt, u, f, p, uprev = integrator - - reinitFBDF!(integrator, cache) - k = order - @.. broadcast=false u₀=zero(u) #predictor - tdt = t + dt - if cache.iters_from_event >= 1 - calc_Lagrange_interp!(k, weights, tdt, ts, u_history, u₀) - else - @.. broadcast=false u₀=u - end - markfirststage!(nlsolver) - @.. broadcast=false nlsolver.z=u₀ - mass_matrix = f.mass_matrix - - for i in 1:(k - 1) - equi_ts[i] = t - dt * i - end - - fill!(u_corrector, zero(eltype(u))) - for i in 1:(k - 1) - @views calc_Lagrange_interp!(k, weights, equi_ts[i], ts, u_history, - u_corrector[:, i]) - end - @.. broadcast=false tmp=-uprev * bdf_coeffs[k, 2] - vc = _vec(tmp) - for i in 1:(k - 1) - @.. broadcast=false @views vc -= u_corrector[:, i] * bdf_coeffs[k, i + 2] - end - - invdt = inv(dt) - if mass_matrix === I - @.. broadcast=false nlsolver.tmp=tmp * invdt - else - @.. broadcast=false terkp1_tmp=tmp * invdt - mul!(nlsolver.tmp, mass_matrix, terkp1_tmp) - end - - β₀ = inv(bdf_coeffs[k, 1]) - α₀ = 1 - nlsolver.γ = β₀ - nlsolver.α = α₀ - nlsolver.method = COEFFICIENT_MULTISTEP - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=z - - step_limiter!(u, integrator, p, t + dt) - - #This is to correct the interpolation error of error estimation. - for j in 2:k - r[j] = (1 - j) - for i in 2:(k + 1) - r[j] *= ((tdt - j * dt) - ts[i]) / (i * dt) - end - end - - #for terkp1, we could use corrector and predictor to make an estimation. - @.. broadcast=false terkp1_tmp=(u - u₀) - for j in 1:(k + 1) - @.. broadcast=false terkp1_tmp*=j * dt / (tdt - ts[j]) - end - - lte = -1 / (1 + k) - for j in 2:k - lte -= bdf_coeffs[k, j] * r[j] - end - @.. broadcast=false terk_tmp=lte * terkp1_tmp - if integrator.opts.adaptive - @unpack abstol, reltol, internalnorm = integrator.opts - for i in 1:(k + 1) - ts_tmp[i + 1] = ts[i] - end - ts_tmp[1] = tdt - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, - internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - estimate_terk!(integrator, cache, k + 1, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), abstol, reltol, - internalnorm, t) - cache.terk = integrator.opts.internalnorm(atmp, t) - - if k > 1 - estimate_terk!(integrator, cache, k, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm1 = integrator.opts.internalnorm(atmp, t) - end - if k > 2 - estimate_terk!(integrator, cache, k - 1, Val(max_order)) - calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkm2 = integrator.opts.internalnorm(atmp, t) - end - if cache.nconsteps > k + 1 && k < max_order - calculate_residuals!(atmp, _vec(terkp1_tmp), _vec(uprev), _vec(u), - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - cache.terkp1 = integrator.opts.internalnorm(atmp, t) - else - cache.terkp1 = zero(cache.terkp1) - end - end - - f(integrator.fsallast, u, p, tdt) - integrator.stats.nf += 1 -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/Project.toml b/lib/OrdinaryDiffEqExplicitRK/Project.toml deleted file mode 100644 index fd4223b529..0000000000 --- a/lib/OrdinaryDiffEqExplicitRK/Project.toml +++ /dev/null @@ -1,24 +0,0 @@ -name = "OrdinaryDiffEqExplicitRK" -uuid = "a6f9a3f1-1c5b-4457-b8d8-bad5275751bf" -authors = ["ParamThakkar123 "] -version = "0.1.0" - -[deps] -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" -RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" - -[compat] -julia = "1.10" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl b/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl deleted file mode 100644 index 8e04177dc8..0000000000 --- a/lib/OrdinaryDiffEqExplicitRK/src/OrdinaryDiffEqExplicitRK.jl +++ /dev/null @@ -1,22 +0,0 @@ -module OrdinaryDiffEqExplicitRK - -import OrdinaryDiffEq: alg_order, calculate_residuals!, - initialize!, perform_step!, @unpack, unwrap_alg, - calculate_residuals, alg_extrapolates, - OrdinaryDiffEqAlgorithm, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqAdaptivePartitionedAlgorithm, - OrdinaryDiffEqPartitionedAlgorithm, - OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, - alg_cache, _vec, _reshape, @cache, isfsal, full_cache, - constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools -using DiffEqBase: @def, @tight_loop_macros - -include("algorithms.jl") -include("alg_utils.jl") -include("explicit_rk_caches.jl") -include("explicit_rk_perform_step.jl") - -end diff --git a/lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl b/lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl deleted file mode 100644 index 7e0b5ed0ea..0000000000 --- a/lib/OrdinaryDiffEqExplicitRK/src/alg_utils.jl +++ /dev/null @@ -1,7 +0,0 @@ -isfsal(tab::DiffEqBase.ExplicitRKTableau) = tab.fsal - -alg_order(alg::ExplicitRK) = alg.tableau.order - -alg_adaptive_order(alg::ExplicitRK) = alg.tableau.adaptiveorder - -alg_stability_size(alg::ExplicitRK) = alg.tableau.stability_size \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl b/lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl deleted file mode 100644 index 39f6b6ba79..0000000000 --- a/lib/OrdinaryDiffEqExplicitRK/src/algorithms.jl +++ /dev/null @@ -1,6 +0,0 @@ -struct ExplicitRK{TabType} <: OrdinaryDiffEqAdaptiveAlgorithm - tableau::TabType -end -ExplicitRK(; tableau = ODE_DEFAULT_TABLEAU) = ExplicitRK(tableau) - -TruncatedStacktraces.@truncate_stacktrace ExplicitRK \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl b/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl deleted file mode 100644 index f2234f843c..0000000000 --- a/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_caches.jl +++ /dev/null @@ -1,60 +0,0 @@ -@cache struct ExplicitRKCache{uType, rateType, uNoUnitsType, TabType} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - utilde::rateType - atmp::uNoUnitsType - fsalfirst::rateType - fsallast::rateType - kk::Vector{rateType} - tab::TabType -end - -TruncatedStacktraces.@truncate_stacktrace ExplicitRKCache 1 - -function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - kk = Vector{typeof(rate_prototype)}(undef, 0) - for i in 1:(alg.tableau.stages) - push!(kk, zero(rate_prototype)) - end - fsalfirst = kk[1] - if isfsal(alg.tableau) - fsallast = kk[end] - else - fsallast = zero(rate_prototype) - end - utilde = zero(rate_prototype) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tab = ExplicitRKConstantCache(alg.tableau, rate_prototype) - ExplicitRKCache(u, uprev, tmp, utilde, atmp, fsalfirst, fsallast, kk, tab) -end - -struct ExplicitRKConstantCache{MType, VType, KType} <: OrdinaryDiffEqConstantCache - A::MType - c::VType - α::VType - αEEst::VType - stages::Int - kk::KType -end - -function ExplicitRKConstantCache(tableau, rate_prototype) - @unpack A, c, α, αEEst, stages = tableau - A = copy(A') # Transpose A to column major looping - kk = Array{typeof(rate_prototype)}(undef, stages) # Not ks since that's for integrator.opts.dense - αEEst = isempty(αEEst) ? αEEst : α .- αEEst - ExplicitRKConstantCache(A, c, α, αEEst, stages, kk) -end - -function alg_cache(alg::ExplicitRK, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - ExplicitRKConstantCache(alg.tableau, rate_prototype) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl b/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl deleted file mode 100644 index 94ea9e4856..0000000000 --- a/lib/OrdinaryDiffEqExplicitRK/src/explicit_rk_perform_step.jl +++ /dev/null @@ -1,240 +0,0 @@ -function initialize!(integrator, cache::ExplicitRKConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::ExplicitRKConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - alg = unwrap_alg(integrator, false) - @unpack A, c, α, αEEst, stages = cache - @unpack kk = cache - - # Calc First - kk[1] = integrator.fsalfirst - - # Calc Middle - for i in 2:(stages - 1) - utilde = zero(kk[1]) - for j in 1:(i - 1) - utilde = utilde + A[j, i] * kk[j] - end - kk[i] = f(uprev + dt * utilde, p, t + c[i] * dt) - integrator.stats.nf += 1 - end - - #Calc Last - utilde_last = zero(kk[1]) - for j in 1:(stages - 1) - utilde_last = utilde_last + A[j, end] * kk[j] - end - u_beforefinal = uprev + dt * utilde_last - kk[end] = f(u_beforefinal, p, t + c[end] * dt) - integrator.stats.nf += 1 - integrator.fsallast = kk[end] # Uses fsallast as temp even if not fsal - - # Accumulate Result - accum = α[1] * kk[1] - for i in 2:stages - accum = accum + α[i] * kk[i] - end - u = uprev + dt * accum - - if integrator.alg isa CompositeAlgorithm - # Hairer II, page 22 modified to use Inf norm - n = maximum(abs.((kk[end] .- kk[end - 1]) / (u .- u_beforefinal))) - integrator.eigen_est = integrator.opts.internalnorm(n, t) - end - - if integrator.opts.adaptive - utilde = αEEst[1] .* kk[1] - for i in 2:stages - utilde = utilde + αEEst[i] * kk[i] - end - atmp = calculate_residuals(dt * utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if !isfsal(alg.tableau) - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - end - - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::ExplicitRKCache) - integrator.kshortsize = 2 - integrator.fsallast = cache.fsallast - integrator.fsalfirst = cache.kk[1] - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@generated function accumulate_explicit_stages!(out, A, uprev, kk, dt, ::Val{s}, - ::Val{r} = Val(s)) where {s, r} - if s == 1 - return :(@muladd @.. broadcast=false out=uprev + dt * kk[1]) - elseif s == 2 - # Note that `A` is transposed - return :(@muladd @.. broadcast=false out=uprev + dt * (A[1, $r] * kk[1])) - else - expr = :(@muladd @.. broadcast=false out=uprev + - dt * (A[1, $r] * kk[1] + A[2, $r] * kk[2])) - acc = expr.args[end].args[end].args[end].args[end].args[end].args - for i in 3:(s - 1) - push!(acc, :(A[$i, $r] * kk[$i])) - end - return expr - end -end - -@generated function accumulate_EEst!(out, αEEst, kk, dt, ::Val{s}) where {s} - if s == 1 - return :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1])) - else - expr = :(@muladd @.. broadcast=false out=dt * (αEEst[1] * kk[1] + αEEst[2] * kk[2])) - acc = expr.args[end].args[end].args[end].args[end].args - for i in 3:s - push!(acc, :(αEEst[$i] * kk[$i])) - end - return expr - end -end - -function accumulate_EEst!(out, αEEst, utilde, kk, dt, stages) - @.. broadcast=false utilde=αEEst[1] * kk[1] - for i in 2:stages - @.. broadcast=false utilde=utilde + αEEst[i] * kk[i] - end - @.. broadcast=false out=dt * utilde -end - -@muladd function compute_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, - stages::Integer) where {F} - # Middle - for i in 2:(stages - 1) - @.. broadcast=false utilde=zero(kk[1][1]) - for j in 1:(i - 1) - @.. broadcast=false utilde=utilde + A[j, i] * kk[j] - end - @.. broadcast=false tmp=uprev + dt * utilde - f(kk[i], tmp, p, t + c[i] * dt) - end - - #Last - @.. broadcast=false utilde=zero(kk[1][1]) - for j in 1:(stages - 1) - @.. broadcast=false utilde=utilde + A[j, end] * kk[j] - end - @.. broadcast=false u=uprev + dt * utilde - f(kk[end], u, p, t + c[end] * dt) #fsallast is tmp even if not fsal - return nothing -end - -@generated function compute_stages!(f::F, A, c, u, tmp, uprev, kk, p, t, dt, - ::Val{s}) where {F, s} - quote - Base.@nexprs $(s - 2) i′->begin - i = i′ + 1 - accumulate_explicit_stages!(tmp, A, uprev, kk, dt, Val(i)) - f(kk[i], tmp, p, t + c[i] * dt) - end - accumulate_explicit_stages!(u, A, uprev, kk, dt, Val(s)) - f(kk[s], u, p, t + c[end] * dt) - end -end - -function runtime_split_stages!(f::F, A, c, utilde, u, tmp, uprev, kk, p, t, dt, - stages::Integer) where {F} - Base.@nif 17 (s->(s == stages)) (s->compute_stages!(f, A, c, u, tmp, uprev, kk, p, t, - dt, Val(s))) (s->compute_stages!(f, - A, - c, - utilde, - u, - tmp, - uprev, - kk, - p, - t, - dt, - stages)) -end - -function accumulate_fsal!(u, α, utilde, uprev, kk, dt, stages) - @.. broadcast=false utilde=α[1] * kk[1] - for i in 2:stages - @.. broadcast=false utilde=utilde + α[i] * kk[i] - end - @.. broadcast=false u=uprev + dt * utilde -end - -function runtime_split_fsal!(out, A, utilde, uprev, kk, dt, stages) - Base.@nif 17 (s->(s == stages)) (s->accumulate_explicit_stages!(out, A, uprev, kk, dt, - Val(s + 1), Val(1))) (s->accumulate_fsal!(out, - A, - utilde, - uprev, - kk, - dt, - stages)) -end - -function runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) - Base.@nif 17 (s->(s == stages)) (s->accumulate_EEst!(tmp, αEEst, kk, dt, Val(s))) (s->accumulate_EEst!( - tmp, - αEEst, - utilde, - kk, - dt, - stages)) -end - -@muladd function perform_step!(integrator, cache::ExplicitRKCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - alg = unwrap_alg(integrator, false) - # αEEst is `α - αEEst` - @unpack A, c, α, αEEst, stages = cache.tab - @unpack kk, utilde, tmp, atmp = cache - - runtime_split_stages!(f, A, c, utilde, u, tmp, uprev, kk, p, t, dt, stages) - integrator.stats.nf += stages - 1 - - #Accumulate - if !isfsal(alg.tableau) - runtime_split_fsal!(u, α, utilde, uprev, kk, dt, stages) - end - - if integrator.alg isa CompositeAlgorithm - # Hairer II, page 22 modified to use Inf norm - @.. broadcast=false utilde=abs((kk[end] - kk[end - 1]) / (u - tmp)) - integrator.eigen_est = integrator.opts.internalnorm(norm(utilde, Inf), t) - end - - if integrator.opts.adaptive - runtime_split_EEst!(tmp, αEEst, utilde, kk, dt, stages) - calculate_residuals!(atmp, tmp, uprev, u, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if !isfsal(alg.tableau) - f(integrator.fsallast, u, p, t + dt) - integrator.stats.nf += 1 - end -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/Project.toml b/lib/OrdinaryDiffEqFIRK/Project.toml deleted file mode 100644 index ac178467a2..0000000000 --- a/lib/OrdinaryDiffEqFIRK/Project.toml +++ /dev/null @@ -1,22 +0,0 @@ -name = "OrdinaryDiffEqFIRK" -uuid = "1072fcc4-aad5-4cac-8081-8f348bae166b" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" - -[compat] -julia = "1.10" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl deleted file mode 100644 index 12f83f81f7..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl +++ /dev/null @@ -1,27 +0,0 @@ -module OrdinaryDiffEqFIRK - -import OrdinaryDiffEq: alg_order, calculate_residuals!, - initialize!, perform_step!, @unpack, unwrap_alg, - calculate_residuals, alg_extrapolates, - OrdinaryDiffEqAlgorithm, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqAdaptivePartitionedAlgorithm, - OrdinaryDiffEqPartitionedAlgorithm, - OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, - alg_cache, _vec, _reshape, @cache, isfsal, full_cache, - constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools -using DiffEqBase: @def, @tight_loop_macros - -include("algorithms.jl") -include("alg_utils.jl") -include("controllers.jl") -include("integrator_interface.jl") -include("firk_tableaus.jl") -include("firk_caches.jl") -include("firk_perform_step.jl") - -export RadauIIA3, RadauIIA5 - -end diff --git a/lib/OrdinaryDiffEqFIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqFIRK/src/alg_utils.jl deleted file mode 100644 index d809df6101..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/alg_utils.jl +++ /dev/null @@ -1,7 +0,0 @@ -qmax_default(alg::Union{RadauIIA3, RadauIIA5}) = 8 - -alg_order(alg::RadauIIA3) = 3 -alg_order(alg::RadauIIA5) = 5 - -alg_adaptive_order(alg::RadauIIA3) = 1 -alg_adaptive_order(alg::RadauIIA5) = 3 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/algorithms.jl b/lib/OrdinaryDiffEqFIRK/src/algorithms.jl deleted file mode 100644 index c57945d9b0..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/algorithms.jl +++ /dev/null @@ -1,106 +0,0 @@ -# FIRK Methods - -""" -@article{hairer1999stiff, -title={Stiff differential equations solved by Radau methods}, -author={Hairer, Ernst and Wanner, Gerhard}, -journal={Journal of Computational and Applied Mathematics}, -volume={111}, -number={1-2}, -pages={93--111}, -year={1999}, -publisher={Elsevier} -} - -RadauIIA3: Fully-Implicit Runge-Kutta Method -An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. -""" -struct RadauIIA3{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - extrapolant::Symbol - κ::Tol - maxiters::Int - fast_convergence_cutoff::C1 - new_W_γdt_cutoff::C2 - controller::Symbol - step_limiter!::StepLimiter -end - -function RadauIIA3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, - extrapolant = :dense, fast_convergence_cutoff = 1 // 5, - new_W_γdt_cutoff = 1 // 5, - controller = :Predictive, κ = nothing, maxiters = 10, - step_limiter! = trivial_limiter!) - RadauIIA3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(fast_convergence_cutoff), - typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, - precs, - extrapolant, - κ, - maxiters, - fast_convergence_cutoff, - new_W_γdt_cutoff, - controller, - step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace RadauIIA3 - -""" -@article{hairer1999stiff, -title={Stiff differential equations solved by Radau methods}, -author={Hairer, Ernst and Wanner, Gerhard}, -journal={Journal of Computational and Applied Mathematics}, -volume={111}, -number={1-2}, -pages={93--111}, -year={1999}, -publisher={Elsevier} -} - -RadauIIA5: Fully-Implicit Runge-Kutta Method -An A-B-L stable fully implicit Runge-Kutta method with internal tableau complex basis transform for efficiency. -""" -struct RadauIIA5{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - smooth_est::Bool - extrapolant::Symbol - κ::Tol - maxiters::Int - fast_convergence_cutoff::C1 - new_W_γdt_cutoff::C2 - controller::Symbol - step_limiter!::StepLimiter -end - -function RadauIIA5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, - extrapolant = :dense, fast_convergence_cutoff = 1 // 5, - new_W_γdt_cutoff = 1 // 5, - controller = :Predictive, κ = nothing, maxiters = 10, smooth_est = true, - step_limiter! = trivial_limiter!) - RadauIIA5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(fast_convergence_cutoff), - typeof(new_W_γdt_cutoff), typeof(step_limiter!)}(linsolve, - precs, - smooth_est, - extrapolant, - κ, - maxiters, - fast_convergence_cutoff, - new_W_γdt_cutoff, - controller, - step_limiter!) -end -TruncatedStacktraces.@truncate_stacktrace RadauIIA5 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/controllers.jl b/lib/OrdinaryDiffEqFIRK/src/controllers.jl deleted file mode 100644 index 254b1c4436..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/controllers.jl +++ /dev/null @@ -1,25 +0,0 @@ -@inline function stepsize_controller!(integrator, controller::PredictiveController, alg) - @unpack qmin, qmax, gamma = integrator.opts - EEst = DiffEqBase.value(integrator.EEst) - - if iszero(EEst) - q = inv(qmax) - else - if fac_default_gamma(alg) - fac = gamma - else - if alg isa Union{RadauIIA3, RadauIIA5} - @unpack iter = integrator.cache - @unpack maxiters = alg - else - @unpack iter, maxiters = integrator.cache.nlsolver - end - fac = min(gamma, (1 + 2 * maxiters) * gamma / (iter + 2 * maxiters)) - end - expo = 1 / (get_current_adaptive_order(alg, integrator.cache) + 1) - qtmp = DiffEqBase.fastpow(EEst, expo) / fac - @fastmath q = DiffEqBase.value(max(inv(qmax), min(inv(qmin), qtmp))) - integrator.qold = q - end - q -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl b/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl deleted file mode 100644 index f294ad9798..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl +++ /dev/null @@ -1,275 +0,0 @@ -mutable struct RadauIIA3ConstantCache{F, Tab, Tol, Dt, U, JType} <: - OrdinaryDiffEqConstantCache - uf::F - tab::Tab - κ::Tol - ηold::Tol - iter::Int - cont1::U - cont2::U - cont3::U - dtprev::Dt - W_γdt::Dt - status::NLStatus - J::JType -end - -function alg_cache(alg::RadauIIA3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - uf = UDerivativeWrapper(f, t, p) - uToltype = constvalue(uBottomEltypeNoUnits) - tab = RadauIIA3Tableau(uToltype, constvalue(tTypeNoUnits)) - - κ = convert(uToltype, 1 // 100) - J = false .* _vec(rate_prototype) .* _vec(rate_prototype)' - - RadauIIA3ConstantCache(uf, tab, κ, one(uToltype), 10000, u, u, u, dt, dt, - Convergence, J) -end - -mutable struct RadauIIA3Cache{uType, cuType, uNoUnitsType, rateType, JType, W1Type, UF, JC, - F1, Tab, Tol, Dt, rTol, aTol, StepLimiter} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - z1::uType - z2::uType - w1::uType - w2::uType - dw12::cuType - cubuff::cuType - cont1::uType - cont2::uType - du1::rateType - fsalfirst::rateType - k::rateType - k2::rateType - fw1::rateType - fw2::rateType - J::JType - W1::W1Type - uf::UF - tab::Tab - κ::Tol - ηold::Tol - iter::Int - tmp::uType - atmp::uNoUnitsType - jac_config::JC - linsolve::F1 - rtol::rTol - atol::aTol - dtprev::Dt - W_γdt::Dt - status::NLStatus - step_limiter!::StepLimiter -end - -function alg_cache(alg::RadauIIA3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - uf = UJacobianWrapper(f, t, p) - uToltype = constvalue(uBottomEltypeNoUnits) - tab = RadauIIA3Tableau(uToltype, constvalue(tTypeNoUnits)) - - κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) - - z1 = zero(u) - z2 = zero(u) - w1 = zero(u) - w2 = zero(u) - dw12 = similar(u, Complex{eltype(u)}) - recursivefill!(dw12, false) - cubuff = similar(u, Complex{eltype(u)}) - recursivefill!(cubuff, false) - cont1 = zero(u) - cont2 = zero(u) - - fsalfirst = zero(rate_prototype) - k = zero(rate_prototype) - k2 = zero(rate_prototype) - fw1 = zero(rate_prototype) - fw2 = zero(rate_prototype) - - J, W1 = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - W1 = similar(J, Complex{eltype(W1)}) - recursivefill!(W1, false) - - du1 = zero(rate_prototype) - - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - jac_config = jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, dw12) - - linprob = LinearProblem(W1, _vec(cubuff); u0 = _vec(dw12)) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - assumptions = LinearSolve.OperatorAssumptions(true)) - #Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), - #Pr = Diagonal(_vec(weight))) - - rtol = reltol isa Number ? reltol : zero(reltol) - atol = reltol isa Number ? reltol : zero(reltol) - - RadauIIA3Cache(u, uprev, - z1, z2, w1, w2, - dw12, cubuff, cont1, cont2, - du1, fsalfirst, k, k2, fw1, fw2, - J, W1, - uf, tab, κ, one(uToltype), 10000, - tmp, atmp, jac_config, linsolve, rtol, atol, dt, dt, - Convergence, alg.step_limiter!) -end - -mutable struct RadauIIA5ConstantCache{F, Tab, Tol, Dt, U, JType} <: - OrdinaryDiffEqConstantCache - uf::F - tab::Tab - κ::Tol - ηold::Tol - iter::Int - cont1::U - cont2::U - cont3::U - dtprev::Dt - W_γdt::Dt - status::NLStatus - J::JType -end - -function alg_cache(alg::RadauIIA5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - uf = UDerivativeWrapper(f, t, p) - uToltype = constvalue(uBottomEltypeNoUnits) - tab = RadauIIA5Tableau(uToltype, constvalue(tTypeNoUnits)) - - κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) - J = false .* _vec(rate_prototype) .* _vec(rate_prototype)' - - RadauIIA5ConstantCache(uf, tab, κ, one(uToltype), 10000, u, u, u, dt, dt, - Convergence, J) -end - -mutable struct RadauIIA5Cache{uType, cuType, uNoUnitsType, rateType, JType, W1Type, W2Type, - UF, JC, F1, F2, Tab, Tol, Dt, rTol, aTol, StepLimiter} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - z1::uType - z2::uType - z3::uType - w1::uType - w2::uType - w3::uType - dw1::uType - ubuff::uType - dw23::cuType - cubuff::cuType - cont1::uType - cont2::uType - cont3::uType - du1::rateType - fsalfirst::rateType - k::rateType - k2::rateType - k3::rateType - fw1::rateType - fw2::rateType - fw3::rateType - J::JType - W1::W1Type - W2::W2Type # complex - uf::UF - tab::Tab - κ::Tol - ηold::Tol - iter::Int - tmp::uType - atmp::uNoUnitsType - jac_config::JC - linsolve1::F1 - linsolve2::F2 - rtol::rTol - atol::aTol - dtprev::Dt - W_γdt::Dt - status::NLStatus - step_limiter!::StepLimiter -end -TruncatedStacktraces.@truncate_stacktrace RadauIIA5Cache 1 - -function alg_cache(alg::RadauIIA5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - uf = UJacobianWrapper(f, t, p) - uToltype = constvalue(uBottomEltypeNoUnits) - tab = RadauIIA5Tableau(uToltype, constvalue(tTypeNoUnits)) - - κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) - - z1 = zero(u) - z2 = zero(u) - z3 = zero(u) - w1 = zero(u) - w2 = zero(u) - w3 = zero(u) - dw1 = zero(u) - ubuff = zero(u) - dw23 = similar(u, Complex{eltype(u)}) - recursivefill!(dw23, false) - cubuff = similar(u, Complex{eltype(u)}) - recursivefill!(cubuff, false) - cont1 = zero(u) - cont2 = zero(u) - cont3 = zero(u) - - fsalfirst = zero(rate_prototype) - k = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - fw1 = zero(rate_prototype) - fw2 = zero(rate_prototype) - fw3 = zero(rate_prototype) - - J, W1 = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - if J isa AbstractSciMLOperator - error("Non-concrete Jacobian not yet supported by RadauIIA5.") - end - W2 = similar(J, Complex{eltype(W1)}) - recursivefill!(W2, false) - - du1 = zero(rate_prototype) - - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, dw1) - - linprob = LinearProblem(W1, _vec(ubuff); u0 = _vec(dw1)) - linsolve1 = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - assumptions = LinearSolve.OperatorAssumptions(true)) - #Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), - #Pr = Diagonal(_vec(weight))) - linprob = LinearProblem(W2, _vec(cubuff); u0 = _vec(dw23)) - linsolve2 = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - assumptions = LinearSolve.OperatorAssumptions(true)) - #Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), - #Pr = Diagonal(_vec(weight))) - - rtol = reltol isa Number ? reltol : zero(reltol) - atol = reltol isa Number ? reltol : zero(reltol) - - RadauIIA5Cache(u, uprev, - z1, z2, z3, w1, w2, w3, - dw1, ubuff, dw23, cubuff, cont1, cont2, cont3, - du1, fsalfirst, k, k2, k3, fw1, fw2, fw3, - J, W1, W2, - uf, tab, κ, one(uToltype), 10000, - tmp, atmp, jac_config, linsolve1, linsolve2, rtol, atol, dt, dt, - Convergence, alg.step_limiter!) -end diff --git a/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl b/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl deleted file mode 100644 index 2ceadc20a1..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl +++ /dev/null @@ -1,751 +0,0 @@ -function do_newJ(integrator, alg, cache, repeat_step)::Bool # for FIRK - integrator.iter <= 1 && return true - repeat_step && return false - first(islinearfunction(integrator)) && return false - integrator.opts.adaptive || return true - alg_can_repeat_jac(alg) || return true - integrator.u_modified && return true - # below is Newton specific logic, so we return non-Newton algs here - alg isa NewtonAlgorithm || return true - nlstatus = cache.status - Int8(nlstatus) < 0 && return true - # no reuse when the cutoff is 0 - fast_convergence_cutoff = alg.fast_convergence_cutoff - iszero(fast_convergence_cutoff) && return true - # reuse J when there is fast convergence - fastconvergence = nlstatus === FastConvergence - return !fastconvergence -end - -function do_newW(integrator, nlsolver, new_jac, W_dt)::Bool # for FIRK - nlsolver === nothing && return true - new_jac && return true - # reuse W when the change in stepsize is small enough - dt = integrator.dt - smallstepchange = abs((dt - W_dt) / W_dt) <= get_new_W_γdt_cutoff(nlsolver) - return !smallstepchange -end - -function initialize!(integrator, cache::RadauIIA3ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - nothing -end - -function initialize!(integrator, cache::RadauIIA5ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - nothing -end - -function initialize!(integrator, cache::RadauIIA3Cache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = cache.k - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - nothing -end - -function initialize!(integrator, cache::RadauIIA5Cache) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = cache.k - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - if integrator.opts.adaptive - @unpack abstol, reltol = integrator.opts - if reltol isa Number - cache.rtol = reltol^(2 / 3) / 10 - cache.atol = cache.rtol * (abstol / reltol) - else - @.. broadcast=false cache.rtol=reltol^(2 / 3) / 10 - @.. broadcast=false cache.atol=cache.rtol * (abstol / reltol) - end - end - nothing -end - -@muladd function perform_step!(integrator, cache::RadauIIA3ConstantCache) - @unpack t, dt, uprev, u, f, p = integrator - @unpack T11, T12, T21, T22, TI11, TI12, TI21, TI22 = cache.tab - @unpack c1, c2, α, β, e1, e2 = cache.tab - @unpack κ, cont1, cont2 = cache - @unpack internalnorm, abstol, reltol, adaptive = integrator.opts - alg = unwrap_alg(integrator, true) - @unpack maxiters = alg - mass_matrix = integrator.f.mass_matrix - - # precalculations - rtol = @. reltol^(2 / 3) / 10 - atol = @. rtol * (abstol / reltol) - αdt, βdt = α / dt, β / dt - J = calc_J(integrator, cache) - - cache.dtprev = one(cache.dtprev) - z1 = w1 = map(zero, u) - z2 = w2 = map(zero, u) - cache.cont1 = map(zero, u) - cache.cont2 = map(zero, u) - - if u isa Number - LU1 = -(αdt + βdt * im) * mass_matrix + J - else - LU1 = lu(-(αdt + βdt * im) * mass_matrix + J) - end - integrator.stats.nw += 1 - - # Newton iteration - local ndw, ff1, ff2 - η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) - fail_convergence = true - iter = 0 - while iter < maxiters - iter += 1 - integrator.stats.nnonliniter += 1 - # evaluate function - ff1 = f(uprev + z1, p, t + c1 * dt) - ff2 = f(uprev + z2, p, t + c2 * dt) - integrator.stats.nf += 2 - - fw1 = @. TI11 * ff1 + TI12 * ff2 - fw2 = @. TI21 * ff1 + TI22 * ff2 - - if mass_matrix isa UniformScaling - Mw1 = @. mass_matrix.λ * w1 - Mw2 = @. mass_matrix.λ * w2 - else - Mw1 = mass_matrix * w1 - Mw2 = mass_matrix * w2 - end - - rhs1 = @. fw1 - αdt * Mw1 + βdt * Mw2 - rhs2 = @. fw2 - βdt * Mw1 - αdt * Mw2 - dw12 = LU1 \ (@. rhs1 + rhs2 * im) - integrator.stats.nsolve += 1 - dw1 = real(dw12) - dw2 = imag(dw12) - - # compute norm of residuals - iter > 1 && (ndwprev = ndw) - atmp1 = calculate_residuals(dw1, uprev, u, atol, rtol, internalnorm, t) - atmp2 = calculate_residuals(dw2, uprev, u, atol, rtol, internalnorm, t) - ndw = internalnorm(atmp1, t) + internalnorm(atmp2, t) - - # check divergence (not in initial step) - if iter > 1 - θ = ndw / ndwprev - (diverge = θ > 1) && (cache.status = Divergence) - (veryslowconvergence = ndw * θ^(maxiters - iter) > κ * (1 - θ)) && - (cache.status = VerySlowConvergence) - if diverge || veryslowconvergence - break - end - end - - w1 = @. w1 - dw1 - w2 = @. w2 - dw2 - - # transform `w` to `z` - z1 = @. T11 * w1 + T12 * w2 - z2 = @. T21 * w1 + T22 * w2 - - # check stopping criterion - iter > 1 && (η = θ / (1 - θ)) - if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) - # Newton method converges - cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : - Convergence - fail_convergence = false - break - end - end - - cache.ηold = η - cache.iter = iter - - u = @. uprev + z2 - - if adaptive - utilde = @. dt * (e1 * ff1 + e2 * ff2) - atmp = calculate_residuals(utilde, uprev, u, atol, rtol, internalnorm, t) - integrator.EEst = internalnorm(atmp, t) - end - - integrator.fsallast = f(u, p, t + dt) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -@muladd function perform_step!(integrator, cache::RadauIIA3Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p, fsallast, fsalfirst = integrator - @unpack T11, T12, T21, T22, TI11, TI12, TI21, TI22 = cache.tab - @unpack c1, c2, α, β, e1, e2 = cache.tab - @unpack κ, cont1, cont2 = cache - @unpack z1, z2, w1, w2, - dw12, cubuff, - k, k2, fw1, fw2, - J, W1, - tmp, atmp, jac_config, rtol, atol, step_limiter! = cache - @unpack internalnorm, abstol, reltol, adaptive = integrator.opts - alg = unwrap_alg(integrator, true) - @unpack maxiters = alg - mass_matrix = integrator.f.mass_matrix - # precalculations - αdt, βdt = α / dt, β / dt - (new_jac = do_newJ(integrator, alg, cache, repeat_step)) && - (calc_J!(J, integrator, cache); cache.W_γdt = dt) - if (new_W = do_newW(integrator, alg, new_jac, cache.W_γdt)) - @inbounds for II in CartesianIndices(J) - W1[II] = -(αdt + βdt * im) * mass_matrix[Tuple(II)...] + J[II] - end - integrator.stats.nw += 1 - end - - #better initial guess - uzero = zero(eltype(z1)) - @. z1 = uzero - @. z2 = uzero - @. w1 = uzero - @. w2 = uzero - @. cache.cont1 = uzero - @. cache.cont2 = uzero - - # Newton iteration - local ndw - η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) - fail_convergence = true - iter = 0 - while iter < maxiters - iter += 1 - integrator.stats.nnonliniter += 1 - # evaluate function - @. tmp = uprev + z1 - f(fsallast, tmp, p, t + c1 * dt) - @. tmp = uprev + z2 - f(k2, tmp, p, t + c2 * dt) - integrator.stats.nf += 2 - - @. fw1 = TI11 * fsallast + TI12 * k2 - @. fw2 = TI21 * fsallast + TI22 * k2 - - if mass_matrix === I - Mw1 = w1 - Mw2 = w2 - elseif mass_matrix isa UniformScaling - mul!(z1, mass_matrix.λ, w1) - mul!(z2, mass_matrix.λ, w2) - Mw1 = z1 - Mw2 = z2 - else - mul!(z1, mass_matrix, w1) - mul!(z2, mass_matrix, w2) - Mw1 = z1 - Mw2 = z2 - end - - @. cubuff = complex(fw1 - αdt * Mw1 + βdt * Mw2, fw2 - βdt * Mw1 - αdt * Mw2) - needfactor = iter == 1 - - linsolve = cache.linsolve - - if needfactor - linres = dolinsolve(integrator, linsolve; A = W1, b = _vec(cubuff), - linu = _vec(dw12)) - else - linres = dolinsolve(integrator, linsolve; A = nothing, b = _vec(cubuff), - linu = _vec(dw12)) - end - - cache.linsolve = linres.cache - - integrator.stats.nsolve += 1 - dw1 = real(dw12) - dw2 = imag(dw12) - - # compute norm of residuals - iter > 1 && (ndwprev = ndw) - calculate_residuals!(atmp, dw1, uprev, u, atol, rtol, internalnorm, t) - ndw1 = internalnorm(atmp, t) - calculate_residuals!(atmp, dw2, uprev, u, atol, rtol, internalnorm, t) - ndw2 = internalnorm(atmp, t) - ndw = ndw1 + ndw2 - - # check divergence (not in initial step) - if iter > 1 - θ = ndw / ndwprev - (diverge = θ > 2) && (cache.status = Divergence) - if diverge - break - end - end - - @. w1 = w1 - dw1 - @. w2 = w2 - dw2 - - # transform `w` to `z` - @. z1 = T11 * w1 + T12 * w2 - @. z2 = T21 * w1 + T22 * w2 - - # check stopping criterion - iter > 1 && (η = θ / (1 - θ)) - if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) - # Newton method converges - cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : - Convergence - fail_convergence = false - break - end - end - if fail_convergence - integrator.force_stepfail = true - integrator.stats.nnonlinconvfail += 1 - return - end - cache.ηold = η - cache.iter = iter - - @. u = uprev + z2 - step_limiter!(u, integrator, p, t + dt) - - if adaptive - utilde = w2 - @. utilde = dt * (e1 * fsallast + e2 * k2) - calculate_residuals!(atmp, utilde, uprev, u, atol, rtol, internalnorm, t) - integrator.EEst = internalnorm(atmp, t) - end - f(fsallast, u, p, t + dt) - integrator.stats.nf += 1 - return -end - -@muladd function perform_step!(integrator, cache::RadauIIA5ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack T11, T12, T13, T21, T22, T23, T31, TI11, TI12, TI13, TI21, TI22, TI23, TI31, TI32, TI33 = cache.tab - @unpack c1, c2, γ, α, β, e1, e2, e3 = cache.tab - @unpack κ, cont1, cont2, cont3 = cache - @unpack internalnorm, abstol, reltol, adaptive = integrator.opts - alg = unwrap_alg(integrator, true) - @unpack maxiters = alg - mass_matrix = integrator.f.mass_matrix - - # precalculations - rtol = @.. broadcast=false reltol^(2 / 3)/10 - atol = @.. broadcast=false rtol*(abstol / reltol) - c1m1 = c1 - 1 - c2m1 = c2 - 1 - c1mc2 = c1 - c2 - γdt, αdt, βdt = γ / dt, α / dt, β / dt - J = calc_J(integrator, cache) - if u isa Number - LU1 = -γdt * mass_matrix + J - LU2 = -(αdt + βdt * im) * mass_matrix + J - else - LU1 = lu(-γdt * mass_matrix + J) - LU2 = lu(-(αdt + βdt * im) * mass_matrix + J) - end - integrator.stats.nw += 1 - - # TODO better initial guess - if integrator.iter == 1 || integrator.u_modified || alg.extrapolant == :constant - cache.dtprev = one(cache.dtprev) - z1 = w1 = map(zero, u) - z2 = w2 = map(zero, u) - z3 = w3 = map(zero, u) - cache.cont1 = map(zero, u) - cache.cont2 = map(zero, u) - cache.cont3 = map(zero, u) - else - c3′ = dt / cache.dtprev - c1′ = c1 * c3′ - c2′ = c2 * c3′ - z1 = @.. broadcast=false c1′*(cont1 + (c1′ - c2m1) * (cont2 + (c1′ - c1m1) * cont3)) - z2 = @.. broadcast=false c2′*(cont1 + (c2′ - c2m1) * (cont2 + (c2′ - c1m1) * cont3)) - z3 = @.. broadcast=false c3′*(cont1 + (c3′ - c2m1) * (cont2 + (c3′ - c1m1) * cont3)) - w1 = @.. broadcast=false TI11*z1+TI12*z2+TI13*z3 - w2 = @.. broadcast=false TI21*z1+TI22*z2+TI23*z3 - w3 = @.. broadcast=false TI31*z1+TI32*z2+TI33*z3 - end - - # Newton iteration - local ndw - η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) - fail_convergence = true - iter = 0 - while iter < maxiters - iter += 1 - integrator.stats.nnonliniter += 1 - - # evaluate function - ff1 = f(uprev + z1, p, t + c1 * dt) - ff2 = f(uprev + z2, p, t + c2 * dt) - ff3 = f(uprev + z3, p, t + dt) # c3 = 1 - integrator.stats.nf += 3 - - fw1 = @.. broadcast=false TI11*ff1+TI12*ff2+TI13*ff3 - fw2 = @.. broadcast=false TI21*ff1+TI22*ff2+TI23*ff3 - fw3 = @.. broadcast=false TI31*ff1+TI32*ff2+TI33*ff3 - - if mass_matrix isa UniformScaling # `UniformScaling` doesn't play nicely with broadcast - Mw1 = @.. broadcast=false mass_matrix.λ*w1 - Mw2 = @.. broadcast=false mass_matrix.λ*w2 - Mw3 = @.. broadcast=false mass_matrix.λ*w3 - else - Mw1 = mass_matrix * w1 - Mw2 = mass_matrix * w2 - Mw3 = mass_matrix * w3 - end - - rhs1 = @.. broadcast=false fw1-γdt * Mw1 - rhs2 = @.. broadcast=false fw2 - αdt * Mw2+βdt * Mw3 - rhs3 = @.. broadcast=false fw3 - βdt * Mw2-αdt * Mw3 - dw1 = LU1 \ rhs1 - dw23 = LU2 \ (@.. broadcast=false rhs2+rhs3 * im) - integrator.stats.nsolve += 2 - dw2 = real(dw23) - dw3 = imag(dw23) - - # compute norm of residuals - iter > 1 && (ndwprev = ndw) - atmp1 = calculate_residuals(dw1, uprev, u, atol, rtol, internalnorm, t) - atmp2 = calculate_residuals(dw2, uprev, u, atol, rtol, internalnorm, t) - atmp3 = calculate_residuals(dw3, uprev, u, atol, rtol, internalnorm, t) - ndw = internalnorm(atmp1, t) + internalnorm(atmp2, t) + internalnorm(atmp3, t) - - # check divergence (not in initial step) - if iter > 1 - θ = ndw / ndwprev - (diverge = θ > 1) && (cache.status = Divergence) - (veryslowconvergence = ndw * θ^(maxiters - iter) > κ * (1 - θ)) && - (cache.status = VerySlowConvergence) - if diverge || veryslowconvergence - break - end - end - - w1 = @.. broadcast=false w1-dw1 - w2 = @.. broadcast=false w2-dw2 - w3 = @.. broadcast=false w3-dw3 - - # transform `w` to `z` - z1 = @.. broadcast=false T11*w1+T12*w2+T13*w3 - z2 = @.. broadcast=false T21*w1+T22*w2+T23*w3 - z3 = @.. broadcast=false T31 * w1+w2 # T32 = 1, T33 = 0 - - # check stopping criterion - iter > 1 && (η = θ / (1 - θ)) - if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) - # Newton method converges - cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : - Convergence - fail_convergence = false - break - end - end - if fail_convergence - integrator.force_stepfail = true - integrator.stats.nnonlinconvfail += 1 - return - end - cache.ηold = η - cache.iter = iter - - u = @.. broadcast=false uprev+z3 - - if adaptive - e1dt, e2dt, e3dt = e1 / dt, e2 / dt, e3 / dt - tmp = @.. broadcast=false e1dt*z1+e2dt*z2+e3dt*z3 - mass_matrix != I && (tmp = mass_matrix * tmp) - utilde = @.. broadcast=false integrator.fsalfirst+tmp - alg.smooth_est && (utilde = LU1 \ utilde; integrator.stats.nsolve += 1) - # RadauIIA5 needs a transformed rtol and atol see - # https://github.com/luchr/ODEInterface.jl/blob/0bd134a5a358c4bc13e0fb6a90e27e4ee79e0115/src/radau5.f#L399-L421 - atmp = calculate_residuals(utilde, uprev, u, atol, rtol, internalnorm, t) - integrator.EEst = internalnorm(atmp, t) - - if !(integrator.EEst < oneunit(integrator.EEst)) && integrator.iter == 1 || - integrator.u_modified - f0 = f(uprev .+ utilde, p, t) - integrator.stats.nf += 1 - utilde = @.. broadcast=false f0+tmp - alg.smooth_est && (utilde = LU1 \ utilde; integrator.stats.nsolve += 1) - atmp = calculate_residuals(utilde, uprev, u, atol, rtol, internalnorm, t) - integrator.EEst = internalnorm(atmp, t) - end - end - - if integrator.EEst <= oneunit(integrator.EEst) - cache.dtprev = dt - if alg.extrapolant != :constant - cache.cont1 = @.. broadcast=false (z2 - z3)/c2m1 - tmp = @.. broadcast=false (z1 - z2)/c1mc2 - cache.cont2 = @.. broadcast=false (tmp - cache.cont1)/c1m1 - cache.cont3 = @.. broadcast=false cache.cont2-(tmp - z1 / c1) / c2 - end - end - - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -@muladd function perform_step!(integrator, cache::RadauIIA5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p, fsallast, fsalfirst = integrator - @unpack T11, T12, T13, T21, T22, T23, T31, TI11, TI12, TI13, TI21, TI22, TI23, TI31, TI32, TI33 = cache.tab - @unpack c1, c2, γ, α, β, e1, e2, e3 = cache.tab - @unpack κ, cont1, cont2, cont3 = cache - @unpack z1, z2, z3, w1, w2, w3, - dw1, ubuff, dw23, cubuff, - k, k2, k3, fw1, fw2, fw3, - J, W1, W2, - tmp, atmp, jac_config, linsolve1, linsolve2, rtol, atol, step_limiter! = cache - @unpack internalnorm, abstol, reltol, adaptive = integrator.opts - alg = unwrap_alg(integrator, true) - @unpack maxiters = alg - mass_matrix = integrator.f.mass_matrix - - # precalculations - c1m1 = c1 - 1 - c2m1 = c2 - 1 - c1mc2 = c1 - c2 - γdt, αdt, βdt = γ / dt, α / dt, β / dt - (new_jac = do_newJ(integrator, alg, cache, repeat_step)) && - (calc_J!(J, integrator, cache); cache.W_γdt = dt) - if (new_W = do_newW(integrator, alg, new_jac, cache.W_γdt)) - @inbounds for II in CartesianIndices(J) - W1[II] = -γdt * mass_matrix[Tuple(II)...] + J[II] - W2[II] = -(αdt + βdt * im) * mass_matrix[Tuple(II)...] + J[II] - end - integrator.stats.nw += 1 - end - - # TODO better initial guess - if integrator.iter == 1 || integrator.u_modified || alg.extrapolant == :constant - cache.dtprev = one(cache.dtprev) - uzero = zero(eltype(u)) - @.. broadcast=false z1=uzero - @.. broadcast=false z2=uzero - @.. broadcast=false z3=uzero - @.. broadcast=false w1=uzero - @.. broadcast=false w2=uzero - @.. broadcast=false w3=uzero - @.. broadcast=false cache.cont1=uzero - @.. broadcast=false cache.cont2=uzero - @.. broadcast=false cache.cont3=uzero - else - c3′ = dt / cache.dtprev - c1′ = c1 * c3′ - c2′ = c2 * c3′ - @.. broadcast=false z1=c1′ * (cont1 + (c1′ - c2m1) * (cont2 + (c1′ - c1m1) * cont3)) - @.. broadcast=false z2=c2′ * (cont1 + (c2′ - c2m1) * (cont2 + (c2′ - c1m1) * cont3)) - @.. broadcast=false z3=c3′ * (cont1 + (c3′ - c2m1) * (cont2 + (c3′ - c1m1) * cont3)) - @.. broadcast=false w1=TI11 * z1 + TI12 * z2 + TI13 * z3 - @.. broadcast=false w2=TI21 * z1 + TI22 * z2 + TI23 * z3 - @.. broadcast=false w3=TI31 * z1 + TI32 * z2 + TI33 * z3 - end - - # Newton iteration - local ndw - η = max(cache.ηold, eps(eltype(integrator.opts.reltol)))^(0.8) - fail_convergence = true - iter = 0 - while iter < maxiters - iter += 1 - integrator.stats.nnonliniter += 1 - - # evaluate function - @.. broadcast=false tmp=uprev + z1 - f(fsallast, tmp, p, t + c1 * dt) - @.. broadcast=false tmp=uprev + z2 - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false tmp=uprev + z3 - f(k3, tmp, p, t + dt) # c3 = 1 - integrator.stats.nf += 3 - - @.. broadcast=false fw1=TI11 * fsallast + TI12 * k2 + TI13 * k3 - @.. broadcast=false fw2=TI21 * fsallast + TI22 * k2 + TI23 * k3 - @.. broadcast=false fw3=TI31 * fsallast + TI32 * k2 + TI33 * k3 - - if mass_matrix === I - Mw1 = w1 - Mw2 = w2 - Mw3 = w3 - elseif mass_matrix isa UniformScaling - mul!(z1, mass_matrix.λ, w1) - mul!(z2, mass_matrix.λ, w2) - mul!(z3, mass_matrix.λ, w3) - Mw1 = z1 - Mw2 = z2 - Mw3 = z3 - else - mul!(z1, mass_matrix, w1) - mul!(z2, mass_matrix, w2) - mul!(z3, mass_matrix, w3) - Mw1 = z1 - Mw2 = z2 - Mw3 = z3 - end - - @.. broadcast=false ubuff=fw1 - γdt * Mw1 - needfactor = iter == 1 && new_W - - linsolve1 = cache.linsolve1 - - if needfactor - linres1 = dolinsolve(integrator, linsolve1; A = W1, b = _vec(ubuff), - linu = _vec(dw1)) - else - linres1 = dolinsolve(integrator, linsolve1; A = nothing, b = _vec(ubuff), - linu = _vec(dw1)) - end - - cache.linsolve1 = linres1.cache - - @.. broadcast=false cubuff=complex(fw2 - αdt * Mw2 + βdt * Mw3, - fw3 - βdt * Mw2 - αdt * Mw3) - - linsolve2 = cache.linsolve2 - - if needfactor - linres2 = dolinsolve(integrator, linsolve2; A = W2, b = _vec(cubuff), - linu = _vec(dw23)) - else - linres2 = dolinsolve(integrator, linsolve2; A = nothing, b = _vec(cubuff), - linu = _vec(dw23)) - end - - cache.linsolve2 = linres2.cache - - integrator.stats.nsolve += 2 - dw2 = z2 - dw3 = z3 - @.. broadcast=false dw2=real(dw23) - @.. broadcast=false dw3=imag(dw23) - - # compute norm of residuals - iter > 1 && (ndwprev = ndw) - calculate_residuals!(atmp, dw1, uprev, u, atol, rtol, internalnorm, t) - ndw1 = internalnorm(atmp, t) - calculate_residuals!(atmp, dw2, uprev, u, atol, rtol, internalnorm, t) - ndw2 = internalnorm(atmp, t) - calculate_residuals!(atmp, dw3, uprev, u, atol, rtol, internalnorm, t) - ndw3 = internalnorm(atmp, t) - ndw = ndw1 + ndw2 + ndw3 - - # check divergence (not in initial step) - if iter > 1 - θ = ndw / ndwprev - (diverge = θ > 1) && (cache.status = Divergence) - (veryslowconvergence = ndw * θ^(maxiters - iter) > κ * (1 - θ)) && - (cache.status = VerySlowConvergence) - if diverge || veryslowconvergence - break - end - end - - @.. broadcast=false w1=w1 - dw1 - @.. broadcast=false w2=w2 - dw2 - @.. broadcast=false w3=w3 - dw3 - - # transform `w` to `z` - @.. broadcast=false z1=T11 * w1 + T12 * w2 + T13 * w3 - @.. broadcast=false z2=T21 * w1 + T22 * w2 + T23 * w3 - @.. broadcast=false z3=T31 * w1 + w2 # T32 = 1, T33 = 0 - - # check stopping criterion - iter > 1 && (η = θ / (1 - θ)) - if η * ndw < κ && (iter > 1 || iszero(ndw) || !iszero(integrator.success_iter)) - # Newton method converges - cache.status = η < alg.fast_convergence_cutoff ? FastConvergence : - Convergence - fail_convergence = false - break - end - end - if fail_convergence - integrator.force_stepfail = true - integrator.stats.nnonlinconvfail += 1 - return - end - cache.ηold = η - cache.iter = iter - - @.. broadcast=false u=uprev + z3 - step_limiter!(u, integrator, p, t + dt) - - if adaptive - utilde = w2 - e1dt, e2dt, e3dt = e1 / dt, e2 / dt, e3 / dt - @.. broadcast=false tmp=e1dt * z1 + e2dt * z2 + e3dt * z3 - mass_matrix != I && (mul!(w1, mass_matrix, tmp); copyto!(tmp, w1)) - @.. broadcast=false ubuff=integrator.fsalfirst + tmp - - if alg.smooth_est - linres1 = dolinsolve(integrator, linres1.cache; b = _vec(ubuff), - linu = _vec(utilde)) - cache.linsolve1 = linres1.cache - integrator.stats.nsolve += 1 - end - - # RadauIIA5 needs a transformed rtol and atol see - # https://github.com/luchr/ODEInterface.jl/blob/0bd134a5a358c4bc13e0fb6a90e27e4ee79e0115/src/radau5.f#L399-L421 - calculate_residuals!(atmp, utilde, uprev, u, atol, rtol, internalnorm, t) - integrator.EEst = internalnorm(atmp, t) - - if !(integrator.EEst < oneunit(integrator.EEst)) && integrator.iter == 1 || - integrator.u_modified - @.. broadcast=false utilde=uprev + utilde - f(fsallast, utilde, p, t) - integrator.stats.nf += 1 - @.. broadcast=false ubuff=fsallast + tmp - - if alg.smooth_est - linres1 = dolinsolve(integrator, linres1.cache; b = _vec(ubuff), - linu = _vec(utilde)) - cache.linsolve1 = linres1.cache - integrator.stats.nsolve += 1 - end - - calculate_residuals!(atmp, utilde, uprev, u, atol, rtol, internalnorm, t) - integrator.EEst = internalnorm(atmp, t) - end - end - - if integrator.EEst <= oneunit(integrator.EEst) - cache.dtprev = dt - if alg.extrapolant != :constant - @.. broadcast=false cache.cont1=(z2 - z3) / c2m1 - @.. broadcast=false tmp=(z1 - z2) / c1mc2 - @.. broadcast=false cache.cont2=(tmp - cache.cont1) / c1m1 - @.. broadcast=false cache.cont3=cache.cont2 - (tmp - z1 / c1) / c2 - end - end - f(fsallast, u, p, t + dt) - integrator.stats.nf += 1 - return -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl b/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl deleted file mode 100644 index c14cd7eab2..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl +++ /dev/null @@ -1,112 +0,0 @@ -struct RadauIIA3Tableau{T, T2} - T11::T - T12::T - T21::T - T22::T - TI11::T - TI12::T - TI21::T - TI22::T - c1::T2 - c2::T2 - α::T - β::T - e1::T - e2::T -end - -function RadauIIA3Tableau(T, T2) - T11 = T(0.10540925533894596) - T12 = T(-0.29814239699997197) - T21 = T(0.9486832980505138) - T22 = T(0.0) - TI11 = T(0.0) - TI12 = T(1.0540925533894598) - TI21 = T(-3.3541019662496843) - TI22 = T(0.3726779962499649) - c1 = T2(1 / 3) - c2 = T2(1.0) - α = T(2.0) - β = T(-sqrt(2)) - e1 = T(1 / 4) - e2 = T(-1 / 4) - RadauIIA3Tableau{T, T2}(T11, T12, T21, T22, - TI11, TI12, TI21, TI22, - c1, c2, α, β, e1, e2) -end - -struct RadauIIA5Tableau{T, T2} - T11::T - T12::T - T13::T - T21::T - T22::T - T23::T - T31::T - #T32::T = 1 - #T33::T = 0 - TI11::T - TI12::T - TI13::T - TI21::T - TI22::T - TI23::T - TI31::T - TI32::T - TI33::T - c1::T2 - c2::T2 - #c3::T2 = 1 - γ::T - α::T - β::T - e1::T - e2::T - e3::T -end - -# inv(T) * inv(A) * T = [γ 0 0 -# 0 α -β -# 0 β α] -function RadauIIA5Tableau(T, T2) - T11 = convert(T, 9.1232394870892942792e-02) - T12 = convert(T, -0.14125529502095420843e0) - T13 = convert(T, -3.0029194105147424492e-02) - T21 = convert(T, 0.24171793270710701896e0) - T22 = convert(T, 0.20412935229379993199e0) - T23 = convert(T, 0.38294211275726193779e0) - T31 = convert(T, 0.96604818261509293619e0) - TI11 = convert(T, 4.3255798900631553510e0) - TI12 = convert(T, 0.33919925181580986954e0) - TI13 = convert(T, 0.54177053993587487119e0) - TI21 = convert(T, -4.1787185915519047273e0) - TI22 = convert(T, -0.32768282076106238708e0) - TI23 = convert(T, 0.47662355450055045196e0) - TI31 = convert(T, -0.50287263494578687595e0) - TI32 = convert(T, 2.5719269498556054292e0) - TI33 = convert(T, -0.59603920482822492497e0) - - sqrt6 = sqrt(6) - - c1 = convert(T2, (4 - sqrt6) / 10) - c2 = convert(T2, (4 + sqrt6) / 10) - - cbrt9 = cbrt(9) - - γ′ = convert(T, (6.0 + cbrt9 * (cbrt9 - 1)) / 30) # eigval of `A` - α′ = convert(T, (12.0 - cbrt9 * (cbrt9 - 1)) / 60) # eigval of `A` - β′ = convert(T, cbrt9 * (cbrt9 + 1) * sqrt(3) / 60) # eigval of `A` - scale = α′^2 + β′^2 - γ = inv(γ′) # eigval of `inv(A)` - α = α′ / scale # eigval of `inv(A)` - β = β′ / scale # eigval of `inv(A)` - - e1 = convert(T, -(13 + 7 * sqrt6) / 3) - e2 = convert(T, (-13 + 7 * sqrt6) / 3) - e3 = convert(T, -1 / 3) - RadauIIA5Tableau{T, T2}(T11, T12, T13, T21, T22, T23, T31, #= T33 = 0 =# - TI11, TI12, TI13, TI21, TI22, TI23, TI31, TI32, TI33, - c1, c2, #= c3 = 1 =# - γ, α, β, - e1, e2, e3) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl b/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl deleted file mode 100644 index ced31522bf..0000000000 --- a/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl +++ /dev/null @@ -1,4 +0,0 @@ -@inline function DiffEqBase.get_tmp_cache(integrator, alg::Union{RadauIIA3, RadauIIA5}, - cache::OrdinaryDiffEqMutableCache) - (cache.tmp, cache.atmp) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl b/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl deleted file mode 100644 index 562929c255..0000000000 --- a/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl +++ /dev/null @@ -1,54 +0,0 @@ -using OrdinaryDiffEq, DiffEqDevTools, Test, LinearAlgebra -import ODEProblemLibrary: prob_ode_linear, prob_ode_2Dlinear, van - -testTol = 0.2 - -for prob in [prob_ode_linear, prob_ode_2Dlinear] - sim21 = test_convergence(1 .// 2 .^ (6:-1:3), prob, RadauIIA5()) - @test sim21.𝒪est[:final]≈5 atol=testTol -end - -# test adaptivity -for iip in (true, false) - if iip - vanstiff = ODEProblem{iip}(van, [0; sqrt(3)], (0.0, 1.0), 1e6) - else - vanstiff = ODEProblem{false}((u, p, t) -> van(u, p, t), [0; sqrt(3)], (0.0, 1.0), - 1e6) - end - sol = solve(vanstiff, RadauIIA5()) - if iip - @test sol.stats.naccept + sol.stats.nreject > sol.stats.njacs # J reuse - @test sol.stats.njacs < sol.stats.nw # W reuse - end - @test length(sol) < 150 - @test length(solve(remake(vanstiff, p = 1e7), RadauIIA5())) < 150 - @test length(solve(remake(vanstiff, p = 1e7), reltol = [1e-4, 1e-6], RadauIIA5())) < 170 - @test length(solve(remake(vanstiff, p = 1e7), RadauIIA5(), reltol = 1e-9, - abstol = 1e-9)) < 870 - @test length(solve(remake(vanstiff, p = 1e9), RadauIIA5())) < 170 - @test length(solve(remake(vanstiff, p = 1e10), RadauIIA5())) < 190 -end - -##Tests for RadauIIA3 -for prob in [prob_ode_linear, prob_ode_2Dlinear] - dts = 1 ./ 2 .^ (8:-1:1) - sim = test_convergence(dts, prob, RadauIIA3()) - @test sim.𝒪est[:final]≈3 atol=0.25 -end - -# test adaptivity -for iip in (true, false) - if iip - vanstiff = ODEProblem{iip}(van, [0; sqrt(3)], (0.0, 1.0), 1e6) - else - vanstiff = ODEProblem{false}((u, p, t) -> van(u, p, t), [0; sqrt(3)], (0.0, 1.0), - 1e6) - end - sol = solve(vanstiff, RadauIIA3()) - if iip - @test sol.stats.naccept + sol.stats.nreject > sol.stats.njacs # J reuse - @test sol.stats.njacs < sol.stats.nw # W reuse - end - @test length(sol) < 5000 # the error estimate is not very good -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqFIRK/test/runtests.jl b/lib/OrdinaryDiffEqFIRK/test/runtests.jl deleted file mode 100644 index e4e127fb44..0000000000 --- a/lib/OrdinaryDiffEqFIRK/test/runtests.jl +++ /dev/null @@ -1,3 +0,0 @@ -using SafeTestsets - -@time @safetestset "Extrapolation Tests" include("ode_firk_tests.jl") \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/Project.toml b/lib/OrdinaryDiffEqHighOrderRK/Project.toml deleted file mode 100644 index 361738eb0b..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/Project.toml +++ /dev/null @@ -1,22 +0,0 @@ -name = "OrdinaryDiffEqHighOrderRK" -uuid = "3383601e-94d4-44bc-9605-458335d811d3" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" - -[compat] -julia = "1.10" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryHighOrderRK.jl b/lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryHighOrderRK.jl deleted file mode 100644 index 2766202ed6..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/OrdinaryHighOrderRK.jl +++ /dev/null @@ -1,27 +0,0 @@ -module OrdinaryHighOrderRK - -import OrdinaryDiffEq: alg_order, calculate_residuals!, - initialize!, perform_step!, @unpack, unwrap_alg, - calculate_residuals, - OrdinaryDiffEqAlgorithm, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqAdaptiveAlgorithm, OrdinaryDiffEqPartitionedAlgorithm, - CompiledFloats, uses_uprev, - alg_cache, _vec, _reshape, @cache, isfsal, full_cache, - constvalue, _unwrap_val, du_alias_or_new, - explicit_rk_docstring, trivial_limiter!, - _ode_interpolant!, _ode_addsteps! -using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools - -include("algorithms.jl") -include("alg_utils.jl") -include("high_order_rk_caches.jl") -include("interp_func.jl") -include("interpolants.jl") -include("high_order_rk_addsteps.jl") -include("high_order_rk_tableaus.jl") -include("high_order_rk_perform_step.jl") - -export TanYam7, DP8, TsitPap8, PFRK87 - -end diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/alg_utils.jl b/lib/OrdinaryDiffEqHighOrderRK/src/alg_utils.jl deleted file mode 100644 index b86634596f..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/alg_utils.jl +++ /dev/null @@ -1,11 +0,0 @@ -alg_order(alg::TanYam7) = 7 -alg_order(alg::TsitPap8) = 8 -alg_order(alg::PFRK87) = 8 -alg_order(alg::DP8) = 8 - -beta2_default(alg::DP8) = 0 // 1 -beta1_default(alg::DP8, beta2) = typeof(beta2)(1 // alg_order(alg)) - beta2 / 5 - -qmin_default(alg::DP8) = 1 // 3 - -qmax_default(alg::DP8) = 6 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/algorithms.jl b/lib/OrdinaryDiffEqHighOrderRK/src/algorithms.jl deleted file mode 100644 index ef8aa3fdae..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/algorithms.jl +++ /dev/null @@ -1,61 +0,0 @@ -@doc explicit_rk_docstring( - "Tanaka-Yamashita 7 Runge-Kutta method. (7th order interpolant).", - "TanYam7", - references = "Tanaka M., Muramatsu S., Yamashita S., (1992), On the Optimization of Some Nine-Stage - Seventh-order Runge-Kutta Method, Information Processing Society of Japan, - 33 (12), pp. 1512-1526.") -Base.@kwdef struct TanYam7{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function TanYam7(stage_limiter!, step_limiter! = trivial_limiter!) - TanYam7(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Hairer's 8/5/3 adaption of the Dormand-Prince Runge-Kutta method. (7th order interpolant).", - "DP8", - references = "E. Hairer, S.P. Norsett, G. Wanner, (1993) Solving Ordinary Differential Equations I. - Nonstiff Problems. 2nd Edition. Springer Series in Computational Mathematics, - Springer-Verlag.") -Base.@kwdef struct DP8{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function DP8(stage_limiter!, step_limiter! = trivial_limiter!) - DP8(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("Tsitouras-Papakostas 8/7 Runge-Kutta method.", "TsitPap8") -Base.@kwdef struct TsitPap8{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function TsitPap8(stage_limiter!, step_limiter! = trivial_limiter!) - TsitPap8(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("Phase-fitted Runge-Kutta of 8th order.", "PFRK87", - extra_keyword_description = """- `omega`: a periodicity phase estimate, - when accurate this method results in zero numerical dissipation. - """, - extra_keyword_default = "omega = 0.0") -Base.@kwdef struct PFRK87{StageLimiter, StepLimiter, Thread, T} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - omega::T = 0.0 -end -# for backwards compatibility -function PFRK87(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) - PFRK87(stage_limiter!, step_limiter!, False(), omega) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_addsteps.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_addsteps.jl deleted file mode 100644 index 5e1447fb24..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_addsteps.jl +++ /dev/null @@ -1,259 +0,0 @@ -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP8ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 7 || always_calc_begin - @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache - @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache - @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache - k1 = f(uprev, p, t) - k2 = f(uprev + dt * (a0201 * k1), p, t + c2 * dt) - k3 = f(uprev + dt * (a0301 * k1 + a0302 * k2), p, t + c3 * dt) - k4 = f(uprev + dt * (a0401 * k1 + a0403 * k3), p, t + c4 * dt) - k5 = f(uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4), p, t + c5 * dt) - k6 = f(uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5), p, t + c6 * dt) - k7 = f(uprev + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6), p, - t + c7 * dt) - k8 = f( - uprev + - dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + a0807 * k7), - p, - t + c8 * dt) - k9 = f( - uprev + - dt * - (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + a0907 * k7 + - a0908 * k8), - p, t + c9 * dt) - k10 = f( - uprev + - dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + a1007 * k7 + - a1008 * k8 + a1009 * k9), - p, - t + c10 * dt) - k11 = f( - uprev + - dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + a1107 * k7 + - a1108 * k8 + a1109 * k9 + a1110 * k10), - p, - t + c11 * dt) - k12 = f( - uprev + - dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + a1207 * k7 + - a1208 * k8 + a1209 * k9 + a1210 * k10 + a1211 * k11), - p, - t + dt) - kupdate = b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + b10 * k10 + b11 * k11 + - b12 * k12 - utmp = uprev + dt * kupdate - k13 = f(utmp, p, t + dt) - k14 = f( - uprev + - dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + a1409 * k9 + a1410 * k10 + - a1411 * k11 + a1412 * k12 + a1413 * k13), - p, - t + c14 * dt) - k15 = f( - uprev + - dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + a1508 * k8 + a1511 * k11 + - a1512 * k12 + a1513 * k13 + a1514 * k14), - p, - t + c15 * dt) - k16 = f( - uprev + - dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + a1608 * k8 + a1609 * k9 + - a1613 * k13 + a1614 * k14 + a1615 * k15), - p, - t + c16 * dt) - udiff = kupdate - copyat_or_push!(k, 1, udiff) - bspl = k1 - udiff - copyat_or_push!(k, 2, bspl) - copyat_or_push!(k, 3, udiff - k13 - bspl) - copyat_or_push!(k, 4, - (d401 * k1 + d406 * k6 + d407 * k7 + d408 * k8 + d409 * k9 + - d410 * k10 + d411 * k11 + d412 * k12 + d413 * k13 + d414 * k14 + - d415 * k15 + d416 * k16)) - copyat_or_push!(k, 5, - (d501 * k1 + d506 * k6 + d507 * k7 + d508 * k8 + d509 * k9 + - d510 * k10 + d511 * k11 + d512 * k12 + d513 * k13 + d514 * k14 + - d515 * k15 + d516 * k16)) - copyat_or_push!(k, 6, - (d601 * k1 + d606 * k6 + d607 * k7 + d608 * k8 + d609 * k9 + - d610 * k10 + d611 * k11 + d612 * k12 + d613 * k13 + d614 * k14 + - d615 * k15 + d616 * k16)) - copyat_or_push!(k, 7, - (d701 * k1 + d706 * k6 + d707 * k7 + d708 * k8 + d709 * k9 + - d710 * k10 + d711 * k11 + d712 * k12 + d713 * k13 + d714 * k14 + - d715 * k15 + d716 * k16)) - end -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP8Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 7 || always_calc_begin - @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache.tab - @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache.tab - @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache.tab - @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, udiff, bspl, dense_tmp3, dense_tmp4, dense_tmp5, dense_tmp6, dense_tmp7, kupdate, utilde, tmp = cache - utmp = utilde - f(k1, uprev, p, t) - @.. broadcast=false tmp=uprev + dt * (a0201 * k1) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false tmp=uprev + dt * (a0301 * k1 + a0302 * k2) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false tmp=uprev + dt * (a0401 * k1 + a0403 * k3) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false tmp=uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false tmp=uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false tmp=uprev + - dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false tmp=uprev + - dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + - a0807 * k7) - f(k8, tmp, p, t + c8 * dt) - @.. broadcast=false tmp=uprev + - dt * (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + - a0907 * k7 + a0908 * k8) - f(k9, tmp, p, t + c9 * dt) - @.. broadcast=false tmp=uprev + - dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + - a1007 * k7 + a1008 * k8 + a1009 * k9) - f(k10, tmp, p, t + c10 * dt) - @.. broadcast=false tmp=uprev + - dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + - a1107 * k7 + a1108 * k8 + a1109 * k9 + a1110 * k10) - f(k11, tmp, p, t + c11 * dt) - @.. broadcast=false tmp=uprev + - dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + - a1207 * k7 + a1208 * k8 + a1209 * k9 + a1210 * k10 + - a1211 * k11) - f(k12, tmp, p, t + dt) - @.. broadcast=false kupdate=b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + - b10 * k10 + b11 * k11 + b12 * k12 - @.. broadcast=false utmp=uprev + dt * kupdate - f(k13, utmp, p, t + dt) - @.. broadcast=false tmp=uprev + - dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + a1409 * k9 + - a1410 * k10 + a1411 * k11 + a1412 * k12 + a1413 * k13) - f(k14, tmp, p, t + c14 * dt) - @.. broadcast=false tmp=uprev + - dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + a1508 * k8 + - a1511 * k11 + a1512 * k12 + a1513 * k13 + a1514 * k14) - f(k15, tmp, p, t + c15 * dt) - @.. broadcast=false tmp=uprev + - dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + a1608 * k8 + - a1609 * k9 + a1613 * k13 + a1614 * k14 + a1615 * k15) - f(k16, tmp, p, t + c16 * dt) - copyto!(udiff, kupdate) - copyat_or_push!(k, 1, udiff) - @.. broadcast=false tmp=k1 - udiff - copyat_or_push!(k, 2, tmp) - @.. broadcast=false tmp=udiff - k13 - bspl - copyat_or_push!(k, 3, tmp) - @.. broadcast=false tmp=(d401 * k1 + d406 * k6 + d407 * k7 + d408 * k8 + d409 * k9 + - d410 * k10 + d411 * k11 + d412 * k12 + d413 * k13 + - d414 * k14 + d415 * k15 + d416 * k16) - copyat_or_push!(k, 4, tmp) - @.. broadcast=false tmp=(d501 * k1 + d506 * k6 + d507 * k7 + d508 * k8 + d509 * k9 + - d510 * k10 + d511 * k11 + d512 * k12 + d513 * k13 + - d514 * k14 + d515 * k15 + d516 * k16) - copyat_or_push!(k, 5, tmp) - @.. broadcast=false tmp=(d601 * k1 + d606 * k6 + d607 * k7 + d608 * k8 + d609 * k9 + - d610 * k10 + d611 * k11 + d612 * k12 + d613 * k13 + - d614 * k14 + d615 * k15 + d616 * k16) - copyat_or_push!(k, 6, tmp) - @.. broadcast=false tmp=(d701 * k1 + d706 * k6 + d707 * k7 + d708 * k8 + d709 * k9 + - d710 * k10 + d711 * k11 + d712 * k12 + d713 * k13 + - d714 * k14 + d715 * k15 + d716 * k16) - copyat_or_push!(k, 7, tmp) - end -end - -#= -@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::DP8Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) - if length(k)<7 || always_calc_begin - @unpack c7,c8,c9,c10,c11,c6,c5,c4,c3,c2,b1,b6,b7,b8,b9,b10,b11,b12,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211 = cache.tab - @unpack c14,c15,c16,a1401,a1407,a1408,a1409,a1410,a1411,a1412,a1413,a1501,a1506,a1507,a1508,a1511,a1512,a1513,a1514,a1601,a1606,a1607,a1608,a1609,a1613,a1614,a1615 = cache.tab - @unpack d401,d406,d407,d408,d409,d410,d411,d412,d413,d414,d415,d416,d501,d506,d507,d508,d509,d510,d511,d512,d513,d514,d515,d516,d601,d606,d607,d608,d609,d610,d611,d612,d613,d614,d615,d616,d701,d706,d707,d708,d709,d710,d711,d712,d713,d714,d715,d716 = cache.tab - @unpack k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15,k16,udiff,bspl,dense_tmp3,dense_tmp4,dense_tmp5,dense_tmp6,dense_tmp7,kupdate,utilde,tmp = cache - utmp = utilde - k = [cache.udiff,cache.bspl,cache.dense_tmp3,cache.dense_tmp4,cache.dense_tmp5,cache.dense_tmp6,cache.dense_tmp7] - uidx = eachindex(u) - f(k1,uprev,p,t) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0201*k1[i]) - end - f(k2,tmp,p,t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0301*k1[i]+a0302*k2[i]) - end - f(k3,tmp,p,t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0401*k1[i]+a0403*k3[i]) - end - f(k4,tmp,p,t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0501*k1[i]+a0503*k3[i]+a0504*k4[i]) - end - f(k5,tmp,p,t+c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0601*k1[i]+a0604*k4[i]+a0605*k5[i]) - end - f(k6,tmp,p,t+c6*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0701*k1[i]+a0704*k4[i]+a0705*k5[i]+a0706*k6[i]) - end - f(k7,tmp,p,t+c7*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0801*k1[i]+a0804*k4[i]+a0805*k5[i]+a0806*k6[i]+a0807*k7[i]) - end - f(k8,tmp,p,t+c8*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0901*k1[i]+a0904*k4[i]+a0905*k5[i]+a0906*k6[i]+a0907*k7[i]+a0908*k8[i]) - end - f(k9,tmp,p,t+c9*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1001*k1[i]+a1004*k4[i]+a1005*k5[i]+a1006*k6[i]+a1007*k7[i]+a1008*k8[i]+a1009*k9[i]) - end - f(k10,tmp,p,t+c10*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1101*k1[i]+a1104*k4[i]+a1105*k5[i]+a1106*k6[i]+a1107*k7[i]+a1108*k8[i]+a1109*k9[i]+a1110*k10[i]) - end - f(k11,tmp,p,t+c11*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1201*k1[i]+a1204*k4[i]+a1205*k5[i]+a1206*k6[i]+a1207*k7[i]+a1208*k8[i]+a1209*k9[i]+a1210*k10[i]+a1211*k11[i]) - end - f(k12,tmp,p,t+dt) - @tight_loop_macros for i in uidx - @inbounds kupdate[i] = b1*k1[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]+b10*k10[i]+b11*k11[i]+b12*k12[i] - @inbounds utmp[i] = uprev[i] + dt*kupdate[i] - end - f(k13,utmp,p,t+dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1401*k1[i]+a1407*k7[i]+a1408*k8[i]+a1409*k9[i]+a1410*k10[i]+a1411*k11[i]+a1412*k12[i]+a1413*k13[i]) - end - f(k14,tmp,p,t+c14*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1501*k1[i]+a1506*k6[i]+a1507*k7[i]+a1508*k8[i]+a1511*k11[i]+a1512*k12[i]+a1513*k13[i]+a1514*k14[i]) - end - f(k15,tmp,p,t+c15*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1601*k1[i]+a1606*k6[i]+a1607*k7[i]+a1608*k8[i]+a1609*k9[i]+a1613*k13[i]+a1614*k14[i]+a1615*k15[i]) - end - f(k16,tmp,p,t+c16*dt) - @tight_loop_macros for i in uidx - @inbounds udiff[i]= kupdate[i] - @inbounds bspl[i] = k1[i] - udiff[i] - @inbounds k[3][i] = udiff[i] - k13[i] - bspl[i] - @inbounds k[4][i] = (d401*k1[i]+d406*k6[i]+d407*k7[i]+d408*k8[i]+d409*k9[i]+d410*k10[i]+d411*k11[i]+d412*k12[i]+d413*k13[i]+d414*k14[i]+d415*k15[i]+d416*k16[i]) - @inbounds k[5][i] = (d501*k1[i]+d506*k6[i]+d507*k7[i]+d508*k8[i]+d509*k9[i]+d510*k10[i]+d511*k11[i]+d512*k12[i]+d513*k13[i]+d514*k14[i]+d515*k15[i]+d516*k16[i]) - @inbounds k[6][i] = (d601*k1[i]+d606*k6[i]+d607*k7[i]+d608*k8[i]+d609*k9[i]+d610*k10[i]+d611*k11[i]+d612*k12[i]+d613*k13[i]+d614*k14[i]+d615*k15[i]+d616*k16[i]) - @inbounds k[7][i] = (d701*k1[i]+d706*k6[i]+d707*k7[i]+d708*k8[i]+d709*k9[i]+d710*k10[i]+d711*k11[i]+d712*k12[i]+d713*k13[i]+d714*k14[i]+d715*k15[i]+d716*k16[i]) - end - end -end -=# \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_caches.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_caches.jl deleted file mode 100644 index 678ee8416f..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_caches.jl +++ /dev/null @@ -1,265 +0,0 @@ -@cache struct TanYam7Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, - StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - fsalfirst::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - k9::rateType - k10::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - k::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::TanYam7, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = TanYam7ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - k9 = zero(rate_prototype) - k10 = zero(rate_prototype) - utilde = zero(u) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - k = zero(rate_prototype) - TanYam7Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, utilde, tmp, atmp, k, - tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::TanYam7, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - TanYam7ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct DP8Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, - Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - k9::rateType - k10::rateType - k11::rateType - k12::rateType - k13::rateType - k14::rateType - k15::rateType - k16::rateType - kupdate::rateType - udiff::rateType - bspl::rateType - dense_tmp3::rateType - dense_tmp4::rateType - dense_tmp5::rateType - dense_tmp6::rateType - dense_tmp7::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::DP8, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - k9 = zero(rate_prototype) - k10 = zero(rate_prototype) - k11 = zero(rate_prototype) - k12 = zero(rate_prototype) - kupdate = zero(rate_prototype) - utilde = zero(u) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - k13 = zero(rate_prototype) - k14 = zero(rate_prototype) - k15 = zero(rate_prototype) - k16 = zero(rate_prototype) - udiff = zero(rate_prototype) - bspl = zero(rate_prototype) - # dense_tmp1 = udiff - # dense_tmp2 = bspl - dense_tmp3 = zero(rate_prototype) - dense_tmp4 = zero(rate_prototype) - dense_tmp5 = zero(rate_prototype) - dense_tmp6 = zero(rate_prototype) - dense_tmp7 = zero(rate_prototype) - tab = DP8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - DP8Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, - k16, kupdate, - udiff, bspl, dense_tmp3, dense_tmp4, dense_tmp5, dense_tmp6, dense_tmp7, - utilde, tmp, atmp, tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::DP8, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - DP8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct TsitPap8Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, - StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - fsalfirst::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - k9::rateType - k10::rateType - k11::rateType - k12::rateType - k13::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - k::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::TsitPap8, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = TsitPap8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - k9 = zero(rate_prototype) - k10 = zero(rate_prototype) - k11 = zero(rate_prototype) - k12 = zero(rate_prototype) - k13 = zero(rate_prototype) - utilde = zero(u) - k = zero(rate_prototype) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - TsitPap8Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, - tmp, atmp, k, tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::TsitPap8, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - TsitPap8ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct PFRK87Cache{ - uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, - Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - fsalfirst::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - k9::rateType - k10::rateType - k11::rateType - k12::rateType - k13::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - k::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::PFRK87, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = PFRK87ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - k9 = zero(rate_prototype) - k10 = zero(rate_prototype) - k11 = zero(rate_prototype) - k12 = zero(rate_prototype) - k13 = zero(rate_prototype) - utilde = zero(u) - k = zero(rate_prototype) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - PFRK87Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, - tmp, atmp, k, tab, alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::PFRK87, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - PFRK87ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_perform_step.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_perform_step.jl deleted file mode 100644 index 9873cc8cbf..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_perform_step.jl +++ /dev/null @@ -1,1153 +0,0 @@ -function initialize!(integrator, cache::TanYam7ConstantCache) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::TanYam7ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10 = cache - k1 = integrator.fsalfirst - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a43 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4), p, t + c4 * dt) - k6 = f(uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5), p, t + c5 * dt) - k7 = f(uprev + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), p, - t + c6 * dt) - k8 = f(uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7), - p, t + c7 * dt) - k9 = f( - uprev + - dt * - (a91 * k1 + a93 * k3 + a94 * k4 + a95 * k5 + a96 * k6 + a97 * k7 + a98 * k8), - p, - t + dt) - k10 = f( - uprev + - dt * (a101 * k1 + a103 * k3 + a104 * k4 + a105 * k5 + a106 * k6 + a107 * k7 + - a108 * k8), - p, - t + dt) - integrator.stats.nf += 9 - u = uprev + dt * (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9) - if integrator.opts.adaptive - utilde = dt * - (btilde1 * k1 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + btilde7 * k7 + - btilde8 * k8 + btilde9 * k9 + btilde10 * k10) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.fsallast = f(u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::TanYam7Cache) - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = cache.k - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::TanYam7Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack fsalfirst, k2, k3, k4, k5, k6, k7, k8, k9, k10, utilde, tmp, atmp, k, stage_limiter!, step_limiter!, thread = cache - @unpack c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10 = cache.tab - k1 = fsalfirst - f(k1, uprev, p, t) - a = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k6, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + - a76 * k6) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k7, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + - a86 * k6 + - a87 * k7) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k8, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a91 * k1 + a93 * k3 + a94 * k4 + a95 * k5 + - a96 * k6 + - a97 * k7 + a98 * k8) - stage_limiter!(tmp, integrator, p, t + dt) - f(k9, tmp, p, t + dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * - (a101 * k1 + a103 * k3 + a104 * k4 + a105 * k5 + - a106 * k6 + - a107 * k7 + a108 * k8) - stage_limiter!(tmp, integrator, p, t + dt) - f(k10, tmp, p, t + dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + - b8 * k8 + - b9 * k9) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - integrator.stats.nf += 10 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde4 * k4 + - btilde5 * k5 + - btilde6 * k6 + btilde7 * k7 + - btilde8 * k8 + - btilde9 * k9 + btilde10 * k10) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - f(k, u, p, t + dt) - integrator.stats.nf += 1 - return nothing -end - -#= -@muladd function perform_step!(integrator, cache::TanYam7Cache, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - uidx = eachindex(integrator.uprev) - @unpack fsalfirst,k2,k3,k4,k5,k6,k7,k8,k9,k10,utilde,tmp,atmp,k = cache - @unpack c1,c2,c3,c4,c5,c6,c7,a21,a31,a32,a41,a43,a51,a53,a54,a61,a63,a64,a65,a71,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,a91,a93,a94,a95,a96,a97,a98,a101,a103,a104,a105,a106,a107,a108,b1,b4,b5,b6,b7,b8,b9,btilde1,btilde4,btilde5,btilde6,btilde7,btilde8,btilde9,btilde10 = cache.tab - k1 = fsalfirst - f(k1, uprev, p, t) - a = dt*a21 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2, tmp, p, t + c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3, tmp, p, t + c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a43*k3[i]) - end - f(k4, tmp, p, t + c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a53*k3[i]+a54*k4[i]) - end - f(k5, tmp, p, t + c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6, tmp, p, t + c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) - end - f(k7, tmp, p, t + c6*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) - end - f(k8, tmp, p, t + c7*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a91*k1[i]+a93*k3[i]+a94*k4[i]+a95*k5[i]+a96*k6[i]+a97*k7[i]+a98*k8[i]) - end - f(k9, tmp, p, t+dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a101*k1[i]+a103*k3[i]+a104*k4[i]+a105*k5[i]+a106*k6[i]+a107*k7[i]+a108*k8[i]) - end - f(k10, tmp, p, t+dt) - @tight_loop_macros for i in uidx - @inbounds u[i] = uprev[i] + dt*(b1*k1[i]+b4*k4[i]+b5*k5[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]) - end - integrator.stats.nf += 10 - if integrator.opts.adaptive - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(btilde1*k1[i]+btilde4*k4[i]+btilde5*k5[i]+btilde6*k6[i]+btilde7*k7[i]+btilde8*k8[i]+btilde9*k9[i]+btilde10*k10[i]) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - integrator.EEst = integrator.opts.internalnorm(atmp,t) - end - f(k, u, p, t+dt) - integrator.stats.nf += 1 -end -=# - -function initialize!(integrator, cache::DP8ConstantCache) - integrator.kshortsize = 7 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - @inbounds for i in eachindex(integrator.k) - integrator.k[i] = zero(integrator.fsalfirst) - end -end - -@muladd function perform_step!(integrator, cache::DP8ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache - k1 = integrator.fsalfirst - a = dt * a0201 - k2 = f(uprev + a * k1, p, t + c2 * dt) - k3 = f(uprev + dt * (a0301 * k1 + a0302 * k2), p, t + c3 * dt) - k4 = f(uprev + dt * (a0401 * k1 + a0403 * k3), p, t + c4 * dt) - k5 = f(uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4), p, t + c5 * dt) - k6 = f(uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5), p, t + c6 * dt) - k7 = f(uprev + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6), p, t + c7 * dt) - k8 = f( - uprev + dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + a0807 * k7), p, - t + c8 * dt) - k9 = f( - uprev + - dt * - (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + a0907 * k7 + a0908 * k8), - p, - t + c9 * dt) - k10 = f( - uprev + - dt * - (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + a1007 * k7 + a1008 * k8 + - a1009 * k9), - p, - t + c10 * dt) - k11 = f( - uprev + - dt * - (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + a1107 * k7 + a1108 * k8 + - a1109 * k9 + a1110 * k10), - p, - t + c11 * dt) - k12 = f( - uprev + - dt * - (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + a1207 * k7 + a1208 * k8 + - a1209 * k9 + a1210 * k10 + a1211 * k11), - p, - t + dt) - integrator.stats.nf += 11 - kupdate = b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + b10 * k10 + b11 * k11 + - b12 * k12 - u = uprev + dt * kupdate - if integrator.opts.adaptive - utilde = dt * (k1 * er1 + k6 * er6 + k7 * er7 + k8 * er8 + k9 * er9 + k10 * er10 + - k11 * er11 + k12 * er12) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - err5 = integrator.opts.internalnorm(atmp, t) # Order 5 - utilde = dt * - (btilde1 * k1 + btilde6 * k6 + btilde7 * k7 + btilde8 * k8 + btilde9 * k9 + - btilde10 * k10 + btilde11 * k11 + btilde12 * k12) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - err3 = integrator.opts.internalnorm(atmp, t) # Order 3 - err52 = err5 * err5 - if err5 ≈ 0 && err3 ≈ 0 - integrator.EEst = zero(integrator.EEst) - else - integrator.EEst = err52 / sqrt(err52 + 0.01 * err3 * err3) - end - end - k13 = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.fsallast = k13 - if integrator.opts.calck - @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache - @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache - k14 = f( - uprev + - dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + a1409 * k9 + a1410 * k10 + - a1411 * k11 + a1412 * k12 + a1413 * k13), - p, - t + c14 * dt) - k15 = f( - uprev + - dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + a1508 * k8 + a1511 * k11 + - a1512 * k12 + a1513 * k13 + a1514 * k14), - p, - t + c15 * dt) - k16 = f( - uprev + - dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + a1608 * k8 + a1609 * k9 + - a1613 * k13 + a1614 * k14 + a1615 * k15), - p, - t + c16 * dt) - integrator.stats.nf += 3 - udiff = kupdate - integrator.k[1] = udiff - bspl = k1 - udiff - integrator.k[2] = bspl - integrator.k[3] = udiff - k13 - bspl - integrator.k[4] = d401 * k1 + d406 * k6 + d407 * k7 + d408 * k8 + d409 * k9 + - d410 * k10 + d411 * k11 + d412 * k12 + d413 * k13 + d414 * k14 + - d415 * k15 + d416 * k16 - integrator.k[5] = d501 * k1 + d506 * k6 + d507 * k7 + d508 * k8 + d509 * k9 + - d510 * k10 + d511 * k11 + d512 * k12 + d513 * k13 + d514 * k14 + - d515 * k15 + d516 * k16 - integrator.k[6] = d601 * k1 + d606 * k6 + d607 * k7 + d608 * k8 + d609 * k9 + - d610 * k10 + d611 * k11 + d612 * k12 + d613 * k13 + d614 * k14 + - d615 * k15 + d616 * k16 - integrator.k[7] = d701 * k1 + d706 * k6 + d707 * k7 + d708 * k8 + d709 * k9 + - d710 * k10 + d711 * k11 + d712 * k12 + d713 * k13 + d714 * k14 + - d715 * k15 + d716 * k16 - end - integrator.u = u -end - -function initialize!(integrator, cache::DP8Cache) - integrator.kshortsize = 7 - resize!(integrator.k, integrator.kshortsize) - integrator.k .= [ - cache.udiff, - cache.bspl, - cache.dense_tmp3, - cache.dense_tmp4, - cache.dense_tmp5, - cache.dense_tmp6, - cache.dense_tmp7 - ] - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k13 - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::DP8Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - uidx = eachindex(integrator.uprev) - @unpack c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211 = cache.tab - @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, udiff, bspl, dense_tmp3, dense_tmp4, dense_tmp5, dense_tmp6, dense_tmp7, kupdate, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - f(k1, uprev, p, t) - a = dt * a0201 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a0301 * k1 + a0302 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a0401 * k1 + a0403 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0501 * k1 + a0503 * k3 + a0504 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0601 * k1 + a0604 * k4 + a0605 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + - a0706 * k6) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * - (a0801 * k1 + a0804 * k4 + a0805 * k5 + - a0806 * k6 + a0807 * k7) - stage_limiter!(tmp, integrator, p, t + c8 * dt) - f(k8, tmp, p, t + c8 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0901 * k1 + a0904 * k4 + a0905 * k5 + - a0906 * k6 + - a0907 * k7 + a0908 * k8) - stage_limiter!(tmp, integrator, p, t + c9 * dt) - f(k9, tmp, p, t + c9 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + - a1006 * k6 + - a1007 * k7 + a1008 * k8 + a1009 * k9) - stage_limiter!(tmp, integrator, p, t + c10 * dt) - f(k10, tmp, p, t + c10 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + - a1106 * k6 + - a1107 * k7 + a1108 * k8 + a1109 * k9 + - a1110 * k10) - stage_limiter!(tmp, integrator, p, t + c11 * dt) - f(k11, tmp, p, t + c11 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + - a1206 * k6 + - a1207 * k7 + a1208 * k8 + a1209 * k9 + - a1210 * k10 + - a1211 * k11) - stage_limiter!(tmp, integrator, p, t + dt) - f(k12, tmp, p, t + dt) - @.. broadcast=false thread=thread kupdate=b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + - b9 * k9 + - b10 * k10 + b11 * k11 + b12 * k12 - @.. broadcast=false thread=thread u=uprev + dt * kupdate - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - integrator.stats.nf += 12 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * - (k1 * er1 + k6 * er6 + k7 * er7 + - k8 * er8 + k9 * er9 + - k10 * er10 + k11 * er11 + k12 * er12) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - err5 = integrator.opts.internalnorm(atmp, t) # Order 5 - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde6 * k6 + - btilde7 * k7 + - btilde8 * k8 + btilde9 * k9 + - btilde10 * k10 + - btilde11 * k11 + btilde12 * k12) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - err3 = integrator.opts.internalnorm(atmp, t) # Order 3 - err52 = err5 * err5 - if err5 ≈ 0 && err3 ≈ 0 - integrator.EEst = zero(integrator.EEst) - else - integrator.EEst = err52 / sqrt(err52 + 0.01 * err3 * err3) - end - end - f(k13, u, p, t + dt) - integrator.stats.nf += 1 - if integrator.opts.calck - @unpack c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = cache.tab - @unpack d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = cache.tab - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1401 * k1 + a1407 * k7 + a1408 * k8 + - a1409 * k9 + - a1410 * k10 + a1411 * k11 + a1412 * k12 + - a1413 * k13) - f(k14, tmp, p, t + c14 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1501 * k1 + a1506 * k6 + a1507 * k7 + - a1508 * k8 + - a1511 * k11 + a1512 * k12 + a1513 * k13 + - a1514 * k14) - f(k15, tmp, p, t + c15 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1601 * k1 + a1606 * k6 + a1607 * k7 + - a1608 * k8 + - a1609 * k9 + a1613 * k13 + a1614 * k14 + - a1615 * k15) - f(k16, tmp, p, t + c16 * dt) - integrator.stats.nf += 3 - @.. broadcast=false thread=thread udiff=kupdate - @.. broadcast=false thread=thread bspl=k1 - udiff - @.. broadcast=false thread=thread integrator.k[3]=udiff - k13 - bspl - @.. broadcast=false thread=thread integrator.k[4]=d401 * k1 + d406 * k6 + - d407 * k7 + d408 * k8 + - d409 * k9 + d410 * k10 + - d411 * k11 + - d412 * k12 + d413 * k13 + - d414 * k14 + - d415 * k15 + d416 * k16 - @.. broadcast=false thread=thread integrator.k[5]=d501 * k1 + d506 * k6 + - d507 * k7 + d508 * k8 + - d509 * k9 + d510 * k10 + - d511 * k11 + - d512 * k12 + d513 * k13 + - d514 * k14 + - d515 * k15 + d516 * k16 - @.. broadcast=false thread=thread integrator.k[6]=d601 * k1 + d606 * k6 + - d607 * k7 + d608 * k8 + - d609 * k9 + d610 * k10 + - d611 * k11 + - d612 * k12 + d613 * k13 + - d614 * k14 + - d615 * k15 + d616 * k16 - @.. broadcast=false thread=thread integrator.k[7]=d701 * k1 + d706 * k6 + - d707 * k7 + d708 * k8 + - d709 * k9 + d710 * k10 + - d711 * k11 + - d712 * k12 + d713 * k13 + - d714 * k14 + - d715 * k15 + d716 * k16 - end -end - -#= -@muladd function perform_step!(integrator, cache::DP8Cache, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - uidx = eachindex(integrator.uprev) - @unpack c7,c8,c9,c10,c11,c6,c5,c4,c3,c2,b1,b6,b7,b8,b9,b10,b11,b12,btilde1,btilde6,btilde7,btilde8,btilde9,btilde10,btilde11,btilde12,er1,er6,er7,er8,er9,er10,er11,er12,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211 = cache.tab - @unpack k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15,k16,udiff,bspl,dense_tmp3,dense_tmp4,dense_tmp5,dense_tmp6,dense_tmp7,kupdate,utilde,tmp,atmp = cache - f(k1, uprev, p, t) - a = dt*a0201 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2, tmp, p, t + c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0301*k1[i]+a0302*k2[i]) - end - f(k3, tmp, p, t + c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0401*k1[i]+a0403*k3[i]) - end - f(k4, tmp, p, t + c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0501*k1[i]+a0503*k3[i]+a0504*k4[i]) - end - f(k5, tmp, p, t + c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0601*k1[i]+a0604*k4[i]+a0605*k5[i]) - end - f(k6, tmp, p, t + c6*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0701*k1[i]+a0704*k4[i]+a0705*k5[i]+a0706*k6[i]) - end - f(k7, tmp, p, t + c7*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0801*k1[i]+a0804*k4[i]+a0805*k5[i]+a0806*k6[i]+a0807*k7[i]) - end - f(k8, tmp, p, t + c8*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0901*k1[i]+a0904*k4[i]+a0905*k5[i]+a0906*k6[i]+a0907*k7[i]+a0908*k8[i]) - end - f(k9, tmp, p, t + c9*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1001*k1[i]+a1004*k4[i]+a1005*k5[i]+a1006*k6[i]+a1007*k7[i]+a1008*k8[i]+a1009*k9[i]) - end - f(k10, tmp, p, t + c10*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1101*k1[i]+a1104*k4[i]+a1105*k5[i]+a1106*k6[i]+a1107*k7[i]+a1108*k8[i]+a1109*k9[i]+a1110*k10[i]) - end - f(k11, tmp, p, t + c11*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1201*k1[i]+a1204*k4[i]+a1205*k5[i]+a1206*k6[i]+a1207*k7[i]+a1208*k8[i]+a1209*k9[i]+a1210*k10[i]+a1211*k11[i]) - end - f(k12, tmp, p, t+dt) - @tight_loop_macros for i in uidx - @inbounds kupdate[i] = b1*k1[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]+b10*k10[i]+b11*k11[i]+b12*k12[i] - @inbounds u[i] = uprev[i] + dt*kupdate[i] - end - integrator.stats.nf += 12 - if integrator.opts.adaptive - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(k1[i]*er1 + k6[i]*er6 + k7[i]*er7 + k8[i]*er8 + k9[i]*er9 + k10[i]*er10 + k11[i]*er11 + k12[i]*er12) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - err5 = integrator.opts.internalnorm(atmp,t) # Order 5 - @tight_loop_macros for i in uidx - @inbounds utilde[i]= dt*(btilde1*k1[i] + btilde6*k6[i] + btilde7*k7[i] + btilde8*k8[i] + btilde9*k9[i] + btilde10*k10[i] + btilde11*k11[i] + btilde12*k12[i]) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - err3 = integrator.opts.internalnorm(atmp,t) # Order 3 - err52 = err5*err5 - if err5 ≈ 0 && err3 ≈ 0 - integrator.EEst = zero(integrator.EEst) - else - integrator.EEst = err52/sqrt(err52 + 0.01*err3*err3) - end - end - f(k13, u, p, t+dt) - integrator.stats.nf += 1 - if integrator.opts.calck - @unpack c14,c15,c16,a1401,a1407,a1408,a1409,a1410,a1411,a1412,a1413,a1501,a1506,a1507,a1508,a1511,a1512,a1513,a1514,a1601,a1606,a1607,a1608,a1609,a1613,a1614,a1615 = cache.tab - @unpack d401,d406,d407,d408,d409,d410,d411,d412,d413,d414,d415,d416,d501,d506,d507,d508,d509,d510,d511,d512,d513,d514,d515,d516,d601,d606,d607,d608,d609,d610,d611,d612,d613,d614,d615,d616,d701,d706,d707,d708,d709,d710,d711,d712,d713,d714,d715,d716 = cache.tab - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1401*k1[i]+a1407*k7[i]+a1408*k8[i]+a1409*k9[i]+a1410*k10[i]+a1411*k11[i]+a1412*k12[i]+a1413*k13[i]) - end - f(k14, tmp, p, t + c14*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1501*k1[i]+a1506*k6[i]+a1507*k7[i]+a1508*k8[i]+a1511*k11[i]+a1512*k12[i]+a1513*k13[i]+a1514*k14[i]) - end - f(k15, tmp, p, t + c15*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1601*k1[i]+a1606*k6[i]+a1607*k7[i]+a1608*k8[i]+a1609*k9[i]+a1613*k13[i]+a1614*k14[i]+a1615*k15[i]) - end - f(k16, tmp, p, t + c16*dt) - integrator.stats.nf += 3 - @tight_loop_macros for i in uidx - @inbounds udiff[i]= kupdate[i] - @inbounds bspl[i] = k1[i] - udiff[i] - @inbounds integrator.k[3][i] = udiff[i] - k13[i] - bspl[i] - @inbounds integrator.k[4][i] = d401*k1[i]+d406*k6[i]+d407*k7[i]+d408*k8[i]+d409*k9[i]+d410*k10[i]+d411*k11[i]+d412*k12[i]+d413*k13[i]+d414*k14[i]+d415*k15[i]+d416*k16[i] - @inbounds integrator.k[5][i] = d501*k1[i]+d506*k6[i]+d507*k7[i]+d508*k8[i]+d509*k9[i]+d510*k10[i]+d511*k11[i]+d512*k12[i]+d513*k13[i]+d514*k14[i]+d515*k15[i]+d516*k16[i] - @inbounds integrator.k[6][i] = d601*k1[i]+d606*k6[i]+d607*k7[i]+d608*k8[i]+d609*k9[i]+d610*k10[i]+d611*k11[i]+d612*k12[i]+d613*k13[i]+d614*k14[i]+d615*k15[i]+d616*k16[i] - @inbounds integrator.k[7][i] = d701*k1[i]+d706*k6[i]+d707*k7[i]+d708*k8[i]+d709*k9[i]+d710*k10[i]+d711*k11[i]+d712*k12[i]+d713*k13[i]+d714*k14[i]+d715*k15[i]+d716*k16[i] - end - end -end -=# - -function initialize!(integrator, cache::TsitPap8ConstantCache) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -#= -@muladd function perform_step!(integrator, cache::TsitPap8ConstantCache, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - @unpack c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211,a1301,a1304,a1305,a1306,a1307,a1308,a1309,a1310,b1,b6,b7,b8,b9,b10,b11,b12,btilde1,btilde6,btilde7,btilde8,btilde9,btilde10,btilde11,btilde12,btilde13 = cache - k1 = integrator.fsalfirst - a = dt*a0201 - k2 = f(t + c1*dt, @.. broadcast=false uprev+a*k1) - k3 = f(t + c2*dt, @.. broadcast=false uprev+dt*(a0301*k1+a0302*k2)) - k4 = f(t + c3*dt, @.. broadcast=false uprev+dt*(a0401*k1 +a0403*k3)) - k5 = f(t + c4*dt, @.. broadcast=false uprev+dt*(a0501*k1 +a0503*k3+a0504*k4)) - k6 = f(t + c5*dt, @.. broadcast=false uprev+dt*(a0601*k1 +a0604*k4+a0605*k5)) - k7 = f(t + c6*dt, @.. broadcast=false uprev+dt*(a0701*k1 +a0704*k4+a0705*k5+a0706*k6)) - k8 = f(t + c7*dt, @.. broadcast=false uprev+dt*(a0801*k1 +a0804*k4+a0805*k5+a0806*k6+a0807*k7)) - k9 = f(t + c8*dt, @.. broadcast=false uprev+dt*(a0901*k1 +a0904*k4+a0905*k5+a0906*k6+a0907*k7+a0908*k8)) - k10 =f(t + c9*dt, @.. broadcast=false uprev+dt*(a1001*k1 +a1004*k4+a1005*k5+a1006*k6+a1007*k7+a1008*k8+a1009*k9)) - k11= f(t + c10*dt, @.. broadcast=false uprev+dt*(a1101*k1 +a1104*k4+a1105*k5+a1106*k6+a1107*k7+a1108*k8+a1109*k9+a1110*k10)) - k12= f(t+dt, @.. broadcast=false uprev+dt*(a1201*k1 +a1204*k4+a1205*k5+a1206*k6+a1207*k7+a1208*k8+a1209*k9+a1210*k10+a1211*k11)) - k13= f(t+dt, @.. broadcast=false uprev+dt*(a1301*k1 +a1304*k4+a1305*k5+a1306*k6+a1307*k7+a1308*k8+a1309*k9+a1310*k10)) - u = @.. broadcast=false uprev + dt*(b1*k1+b6*k6+b7*k7+b8*k8+b9*k9+b10*k10+b11*k11+b12*k12) - if integrator.opts.adaptive - utilde = @.. broadcast=false dt*(btilde1*k1 + btilde6*k6 + btilde7*k7 + btilde8*k8 + btilde9*k9 + btilde10*k10 + btilde11*k11 + btilde12*k12 + btilde13*k13) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - integrator.EEst = integrator.opts.internalnorm(atmp,t) - end - integrator.fsallast = f(u, p, t+dt) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end -=# - -@muladd function perform_step!(integrator, cache::TsitPap8ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13 = cache - k1 = integrator.fsalfirst - a = dt * a0201 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a0301 * k1 + a0302 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a0401 * k1 + a0403 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a0501 * k1 + a0503 * k3 + a0504 * k4), p, t + c4 * dt) - k6 = f(uprev + dt * (a0601 * k1 + a0604 * k4 + a0605 * k5), p, t + c5 * dt) - k7 = f(uprev + dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + a0706 * k6), p, t + c6 * dt) - k8 = f( - uprev + dt * (a0801 * k1 + a0804 * k4 + a0805 * k5 + a0806 * k6 + a0807 * k7), p, - t + c7 * dt) - k9 = f( - uprev + - dt * - (a0901 * k1 + a0904 * k4 + a0905 * k5 + a0906 * k6 + a0907 * k7 + a0908 * k8), - p, - t + c8 * dt) - k10 = f( - uprev + - dt * - (a1001 * k1 + a1004 * k4 + a1005 * k5 + a1006 * k6 + a1007 * k7 + a1008 * k8 + - a1009 * k9), - p, - t + c9 * dt) - k11 = f( - uprev + - dt * - (a1101 * k1 + a1104 * k4 + a1105 * k5 + a1106 * k6 + a1107 * k7 + a1108 * k8 + - a1109 * k9 + a1110 * k10), - p, - t + c10 * dt) - k12 = f( - uprev + - dt * - (a1201 * k1 + a1204 * k4 + a1205 * k5 + a1206 * k6 + a1207 * k7 + a1208 * k8 + - a1209 * k9 + a1210 * k10 + a1211 * k11), - p, - t + dt) - k13 = f( - uprev + - dt * - (a1301 * k1 + a1304 * k4 + a1305 * k5 + a1306 * k6 + a1307 * k7 + a1308 * k8 + - a1309 * k9 + a1310 * k10), - p, - t + dt) - integrator.stats.nf += 12 - u = uprev + - dt * (b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + b10 * k10 + b11 * k11 + - b12 * k12) - if integrator.opts.adaptive - utilde = dt * - (btilde1 * k1 + btilde6 * k6 + btilde7 * k7 + btilde8 * k8 + btilde9 * k9 + - btilde10 * k10 + btilde11 * k11 + btilde12 * k12 + btilde13 * k13) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::TsitPap8Cache) - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = cache.k - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::TsitPap8Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13 = cache.tab - @unpack k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, tmp, atmp, k, stage_limiter!, step_limiter!, thread = cache - k1 = cache.fsalfirst - f(k1, uprev, p, t) - a = dt * a0201 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a0301 * k1 + a0302 * k2) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a0401 * k1 + a0403 * k3) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0501 * k1 + a0503 * k3 + a0504 * k4) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0601 * k1 + a0604 * k4 + a0605 * k5) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k6, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0701 * k1 + a0704 * k4 + a0705 * k5 + - a0706 * k6) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k7, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * - (a0801 * k1 + a0804 * k4 + a0805 * k5 + - a0806 * k6 + a0807 * k7) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k8, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a0901 * k1 + a0904 * k4 + a0905 * k5 + - a0906 * k6 + - a0907 * k7 + a0908 * k8) - stage_limiter!(tmp, integrator, p, t + c8 * dt) - f(k9, tmp, p, t + c8 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1001 * k1 + a1004 * k4 + a1005 * k5 + - a1006 * k6 + - a1007 * k7 + a1008 * k8 + a1009 * k9) - stage_limiter!(tmp, integrator, p, t + c9 * dt) - f(k10, tmp, p, t + c9 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1101 * k1 + a1104 * k4 + a1105 * k5 + - a1106 * k6 + - a1107 * k7 + a1108 * k8 + a1109 * k9 + - a1110 * k10) - stage_limiter!(tmp, integrator, p, t + c10 * dt) - f(k11, tmp, p, t + c10 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1201 * k1 + a1204 * k4 + a1205 * k5 + - a1206 * k6 + - a1207 * k7 + a1208 * k8 + a1209 * k9 + - a1210 * k10 + - a1211 * k11) - stage_limiter!(tmp, integrator, p, t + dt) - f(k12, tmp, p, t + dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a1301 * k1 + a1304 * k4 + a1305 * k5 + - a1306 * k6 + - a1307 * k7 + a1308 * k8 + a1309 * k9 + - a1310 * k10) - stage_limiter!(tmp, integrator, p, t + dt) - f(k13, tmp, p, t + dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b6 * k6 + b7 * k7 + b8 * k8 + b9 * k9 + - b10 * k10 + - b11 * k11 + b12 * k12) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - integrator.stats.nf += 13 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde6 * k6 + - btilde7 * k7 + - btilde8 * k8 + btilde9 * k9 + - btilde10 * k10 + - btilde11 * k11 + btilde12 * k12 + - btilde13 * k13) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - f(k, u, p, t + dt) - integrator.stats.nf += 1 - return nothing -end - -#= -@muladd function perform_step!(integrator, cache::TsitPap8Cache, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - uidx = eachindex(integrator.uprev) - @unpack c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,a0201,a0301,a0302,a0401,a0403,a0501,a0503,a0504,a0601,a0604,a0605,a0701,a0704,a0705,a0706,a0801,a0804,a0805,a0806,a0807,a0901,a0904,a0905,a0906,a0907,a0908,a1001,a1004,a1005,a1006,a1007,a1008,a1009,a1101,a1104,a1105,a1106,a1107,a1108,a1109,a1110,a1201,a1204,a1205,a1206,a1207,a1208,a1209,a1210,a1211,a1301,a1304,a1305,a1306,a1307,a1308,a1309,a1310,b1,b6,b7,b8,b9,b10,b11,b12,btilde1,btilde6,btilde7,btilde8,btilde9,btilde10,btilde11,btilde12,btilde13 = cache.tab - @unpack k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,utilde,tmp,atmp,k = cache - k1 = cache.fsalfirst - f(k1, uprev, p, t) - a = dt*a0201 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2, tmp, p, t + c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0301*k1[i]+a0302*k2[i]) - end - f(k3, tmp, p, t + c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0401*k1[i]+a0403*k3[i]) - end - f(k4, tmp, p, t + c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0501*k1[i]+a0503*k3[i]+a0504*k4[i]) - end - f(k5, tmp, p, t + c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0601*k1[i]+a0604*k4[i]+a0605*k5[i]) - end - f(k6, tmp, p, t + c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0701*k1[i]+a0704*k4[i]+a0705*k5[i]+a0706*k6[i]) - end - f(k7, tmp, p, t + c6*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0801*k1[i]+a0804*k4[i]+a0805*k5[i]+a0806*k6[i]+a0807*k7[i]) - end - f(k8, tmp, p, t + c7*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a0901*k1[i]+a0904*k4[i]+a0905*k5[i]+a0906*k6[i]+a0907*k7[i]+a0908*k8[i]) - end - f(k9, tmp, p, t + c8*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1001*k1[i]+a1004*k4[i]+a1005*k5[i]+a1006*k6[i]+a1007*k7[i]+a1008*k8[i]+a1009*k9[i]) - end - f(k10, tmp, p, t + c9*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1101*k1[i]+a1104*k4[i]+a1105*k5[i]+a1106*k6[i]+a1107*k7[i]+a1108*k8[i]+a1109*k9[i]+a1110*k10[i]) - end - f(k11, tmp, p, t + c10*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1201*k1[i]+a1204*k4[i]+a1205*k5[i]+a1206*k6[i]+a1207*k7[i]+a1208*k8[i]+a1209*k9[i]+a1210*k10[i]+a1211*k11[i]) - end - f(k12, tmp, p, t+dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a1301*k1[i]+a1304*k4[i]+a1305*k5[i]+a1306*k6[i]+a1307*k7[i]+a1308*k8[i]+a1309*k9[i]+a1310*k10[i]) - end - f(k13, tmp, p, t+dt) - @tight_loop_macros for i in uidx - @inbounds u[i] = uprev[i] + dt*(b1*k1[i]+b6*k6[i]+b7*k7[i]+b8*k8[i]+b9*k9[i]+b10*k10[i]+b11*k11[i]+b12*k12[i]) - end - integrator.stats.nf += 13 - if integrator.opts.adaptive - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde6*k6[i] + btilde7*k7[i] + btilde8*k8[i] + btilde9*k9[i] + btilde10*k10[i] + btilde11*k11[i] + btilde12*k12[i] + btilde13*k13[i]) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - integrator.EEst = integrator.opts.internalnorm(atmp,t) - end - f(k, u, p, t+dt) - integrator.stats.nf += 1 -end -=# - -function initialize!(integrator, cache::PFRK87ConstantCache) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::PFRK87ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack α0201, α0301, α0401, α0501, α0601, α0701, α0302, α0403, α0503, α0504, α0604, α0704, α0605, α0705, α0706, α0908, α1008, α1108, α1208, α1308, α1009, α1109, α1209, α1309, α1110, α1210, α1310, α1211, α1311, β1, β6, β7, β8, β9, β10, β11, β12, β13, β1tilde, β6tilde, β7tilde, β8tilde, β9tilde, β10tilde, β11tilde, β12tilde, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 = cache - alg = unwrap_alg(integrator, false) - ν = alg.omega * dt - νsq = ν^2 - - c_ν = -0.19781108078634084 - (0.164050909125528499 * νsq) + - (0.042578310088756321 * (νsq^2)) - (0.002300513610963998 * (νsq^3)) + - (0.000033467244551879287 * (νsq^4)) - - (7.8661142036921924 * (1 / 100000000) * (νsq^5)) - d_ν = 1 - (0.296457092123567400 * νsq) + (0.0015793885907465726 * (νsq^2)) - - (0.00018913011771688527 * (νsq^3)) + (0.000017089234650765179 * (νsq^4)) - - (1.2705211682518626 * (1 / 10000000) * (νsq^5)) - - α0807 = c_ν / d_ν - α0801 = 0.026876256 + 0.0576576 * α0807 - α0804 = 0.22464336 - 0.944944 * α0807 - α0805 = 0.000369024 - 0.2061696 * α0807 - α0806 = 0.21311136 + 0.093456 * α0807 - α0901 = 0.07239997637512857 + 0.01913119863380767 * α0807 - α0904 = -0.688400520601143 - 0.3135390887207368 * α0807 - α0905 = -0.17301267570583073 - 0.06840852844816077 * α0807 - α0906 = 0.1440060555560846 + 0.031009360422930017 * α0807 - α0907 = 0.9982362892760762 + 0.33180705811215994 * α0807 - α1001 = 0.16261514523236525 - 0.12125171966747463 * α0807 - α1004 = -2.1255544052061124 + 1.9871809612169453 * α0807 - α1005 = -0.216403903283323 + 0.43356675517460624 * α0807 - α1006 = -0.060417230254934076 - 0.1965343807796979 * α0807 - α1007 = 2.4846281621788395 - 2.102961615944379 * α0807 - α1101 = -1.0320124180911034 + 1.061943768952537 * α0807 - α1104 = 13.666683232895137 - 17.40407843561103 * α0807 - α1105 = 0.25990355211486116 - 3.797253476860588 * α0807 - α1106 = -5.759316475814002 + 1.7212824826428488 * α0807 - α1107 = -12.822511612651839 + 18.41810566087623 * α0807 - α1201 = 0.2478349764611783 - 0.06383934946543009 * α0807 - α1204 = -4.593782880309185 + 1.046256005127882 * α0807 - α1205 = -0.39566692537411896 + 0.22827403748244698 * α0807 - α1206 = -3.0673550479691665 - 0.10347586863902129 * α0807 - α1207 = 5.386688702227177 - 1.1072148245058775 * α0807 - α1301 = 0.7332242174431163 - 0.5164807626867616 * α0807 - α1304 = -10.196728938160977 + 8.464545832921925 * α0807 - α1305 = -0.43865244706547707 + 1.846809999910238 * α0807 - α1306 = 0.5693856884667226 - 0.8371528845746959 * α0807 - α1307 = 10.52865228002416 - 8.957722185570706 * α0807 - - k1 = integrator.fsalfirst - k2 = f(uprev + dt * α0201 * k1, p, t + c2 * dt) - k3 = f(uprev + dt * (α0301 * k1 + α0302 * k2), p, t + c3 * dt) - k4 = f(uprev + dt * (α0401 * k1 + α0403 * k3), p, t + c4 * dt) - k5 = f(uprev + dt * (α0501 * k1 + α0503 * k3 + α0504 * k4), p, t + c5 * dt) - k6 = f(uprev + dt * (α0601 * k1 + α0604 * k4 + α0605 * k5), p, t + c6 * dt) - k7 = f(uprev + dt * (α0701 * k1 + α0704 * k4 + α0705 * k5 + α0706 * k6), p, t + c7 * dt) - k8 = f( - uprev + dt * (α0801 * k1 + α0804 * k4 + α0805 * k5 + α0806 * k6 + α0807 * k7), p, - t + c8 * dt) - k9 = f( - uprev + - dt * - (α0901 * k1 + α0904 * k4 + α0905 * k5 + α0906 * k6 + α0907 * k7 + α0908 * k8), - p, - t + c9 * dt) - k10 = f( - uprev + - dt * - (α1001 * k1 + α1004 * k4 + α1005 * k5 + α1006 * k6 + α1007 * k7 + α1008 * k8 + - α1009 * k9), - p, - t + c10 * dt) - k11 = f( - uprev + - dt * - (α1101 * k1 + α1104 * k4 + α1105 * k5 + α1106 * k6 + α1107 * k7 + α1108 * k8 + - α1109 * k9 + α1110 * k10), - p, - t + c11 * dt) - k12 = f( - uprev + - dt * - (α1201 * k1 + α1204 * k4 + α1205 * k5 + α1206 * k6 + α1207 * k7 + α1208 * k8 + - α1209 * k9 + α1210 * k10 + α1211 * k11), - p, - t + c12 * dt) - k13 = f( - uprev + - dt * - (α1301 * k1 + α1304 * k4 + α1305 * k5 + α1306 * k6 + α1307 * k7 + α1308 * k8 + - α1309 * k9 + α1310 * k10 + α1311 * k11), - p, - t + c13 * dt) - integrator.stats.nf += 12 - u = uprev + - dt * (β1 * k1 + β6 * k6 + β7 * k7 + β8 * k8 + β9 * k9 + β10 * k10 + β11 * k11 + - β12 * k12 + β13 * k13) - if integrator.opts.adaptive - utilde = dt * - (β1tilde * k1 + β6tilde * k6 + β7tilde * k7 + β8tilde * k8 + β9tilde * k9 + - β10tilde * k10 + β11tilde * k11 + β12tilde * k12) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::PFRK87Cache) - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = cache.k - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::PFRK87Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack α0201, α0301, α0401, α0501, α0601, α0701, α0302, α0403, α0503, α0504, α0604, α0704, α0605, α0705, α0706, α0908, α1008, α1108, α1208, α1308, α1009, α1109, α1209, α1309, α1110, α1210, α1310, α1211, α1311, β1, β6, β7, β8, β9, β10, β11, β12, β13, β1tilde, β6tilde, β7tilde, β8tilde, β9tilde, β10tilde, β11tilde, β12tilde, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13 = cache.tab - @unpack k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, utilde, tmp, atmp, k, stage_limiter!, step_limiter!, thread = cache - - alg = unwrap_alg(integrator, false) - ν = alg.omega * dt - νsq = ν^2 - - c_ν = -0.19781108078634084 - (0.164050909125528499 * νsq) + - (0.042578310088756321 * (νsq^2)) - (0.002300513610963998 * (νsq^3)) + - (0.000033467244551879287 * (νsq^4)) - (7.8661142036921924 * (10^(-8)) * (νsq^5)) - d_ν = 1 - (0.296457092123567400 * νsq) + (0.0015793885907465726 * (νsq^2)) - - (0.00018913011771688527 * (νsq^3)) + (0.000017089234650765179 * (νsq^4)) - - (1.2705211682518626 * (10^(-7)) * (νsq^5)) - - α0807 = c_ν / d_ν - α0801 = 0.026876256 + 0.0576576 * α0807 - α0804 = 0.22464336 - 0.944944 * α0807 - α0805 = 0.000369024 - 0.2061696 * α0807 - α0806 = 0.21311136 + 0.093456 * α0807 - α0901 = 0.07239997637512857 + 0.01913119863380767 * α0807 - α0904 = -0.688400520601143 - 0.3135390887207368 * α0807 - α0905 = -0.17301267570583073 - 0.06840852844816077 * α0807 - α0906 = 0.1440060555560846 + 0.031009360422930017 * α0807 - α0907 = 0.9982362892760762 + 0.33180705811215994 * α0807 - α1001 = 0.16261514523236525 - 0.12125171966747463 * α0807 - α1004 = -2.1255544052061124 + 1.9871809612169453 * α0807 - α1005 = -0.216403903283323 + 0.43356675517460624 * α0807 - α1006 = -0.060417230254934076 - 0.1965343807796979 * α0807 - α1007 = 2.4846281621788395 - 2.102961615944379 * α0807 - α1101 = -1.0320124180911034 + 1.061943768952537 * α0807 - α1104 = 13.666683232895137 - 17.40407843561103 * α0807 - α1105 = 0.25990355211486116 - 3.797253476860588 * α0807 - α1106 = -5.759316475814002 + 1.7212824826428488 * α0807 - α1107 = -12.822511612651839 + 18.41810566087623 * α0807 - α1201 = 0.2478349764611783 - 0.06383934946543009 * α0807 - α1204 = -4.593782880309185 + 1.046256005127882 * α0807 - α1205 = -0.39566692537411896 + 0.22827403748244698 * α0807 - α1206 = -3.0673550479691665 - 0.10347586863902129 * α0807 - α1207 = 5.386688702227177 - 1.1072148245058775 * α0807 - α1301 = 0.7332242174431163 - 0.5164807626867616 * α0807 - α1304 = -10.196728938160977 + 8.464545832921925 * α0807 - α1305 = -0.43865244706547707 + 1.846809999910238 * α0807 - α1306 = 0.5693856884667226 - 0.8371528845746959 * α0807 - α1307 = 10.52865228002416 - 8.957722185570706 * α0807 - - k1 = cache.fsalfirst - f(k1, uprev, p, t) - @.. broadcast=false thread=thread tmp=uprev + dt * α0201 * k1 - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (α0301 * k1 + α0302 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (α0401 * k1 + α0403 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α0501 * k1 + α0503 * k3 + α0504 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α0601 * k1 + α0604 * k4 + α0605 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α0701 * k1 + α0704 * k4 + α0705 * k5 + - α0706 * k6) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * - (α0801 * k1 + α0804 * k4 + α0805 * k5 + - α0806 * k6 + α0807 * k7) - stage_limiter!(tmp, integrator, p, t + c8 * dt) - f(k8, tmp, p, t + c8 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α0901 * k1 + α0904 * k4 + α0905 * k5 + - α0906 * k6 + - α0907 * k7 + α0908 * k8) - stage_limiter!(tmp, integrator, p, t + c9 * dt) - f(k9, tmp, p, t + c9 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α1001 * k1 + α1004 * k4 + α1005 * k5 + - α1006 * k6 + - α1007 * k7 + α1008 * k8 + α1009 * k9) - stage_limiter!(tmp, integrator, p, t + c10 * dt) - f(k10, tmp, p, t + c10 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α1101 * k1 + α1104 * k4 + α1105 * k5 + - α1106 * k6 + - α1107 * k7 + α1108 * k8 + α1109 * k9 + - α1110 * k10) - stage_limiter!(tmp, integrator, p, t + c11 * dt) - f(k11, tmp, p, t + c11 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α1201 * k1 + α1204 * k4 + α1205 * k5 + - α1206 * k6 + - α1207 * k7 + α1208 * k8 + α1209 * k9 + - α1210 * k10 + - α1211 * k11) - stage_limiter!(tmp, integrator, p, t + c12 * dt) - f(k12, tmp, p, t + c12 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (α1301 * k1 + α1304 * k4 + α1305 * k5 + - α1306 * k6 + - α1307 * k7 + α1308 * k8 + α1309 * k9 + - α1310 * k10 + - α1311 * k11) - stage_limiter!(tmp, integrator, p, t + c13 * dt) - f(k13, tmp, p, t + c13 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (β1 * k1 + β6 * k6 + β7 * k7 + β8 * k8 + β9 * k9 + - β10 * k10 + - β11 * k11 + β12 * k12 + β13 * k13) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - integrator.stats.nf += 13 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (β1tilde * k1 + β6tilde * k6 + - β7tilde * k7 + - β8tilde * k8 + β9tilde * k9 + - β10tilde * k10 + - β11tilde * k11 + β12tilde * k12) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - f(k, u, p, t + dt) - integrator.stats.nf += 1 - return nothing -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_tableaus.jl b/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_tableaus.jl deleted file mode 100644 index 8ca15f91de..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/high_order_rk_tableaus.jl +++ /dev/null @@ -1,1406 +0,0 @@ -struct TanYam7ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - c1::T2 - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - a21::T - a31::T - a32::T - a41::T - a43::T - a51::T - a53::T - a54::T - a61::T - a63::T - a64::T - a65::T - a71::T - a73::T - a74::T - a75::T - a76::T - a81::T - a83::T - a84::T - a85::T - a86::T - a87::T - a91::T - a93::T - a94::T - a95::T - a96::T - a97::T - a98::T - a101::T - a103::T - a104::T - a105::T - a106::T - a107::T - a108::T - b1::T - b4::T - b5::T - b6::T - b7::T - b8::T - b9::T - btilde1::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - btilde8::T - btilde9::T - btilde10::T -end - -""" -On the Optimization of Some Nine-Stage Seventh-order Runge-Kutta Method, by M. Tanaka, S. Muramatsu and S. Yamashita, -Information Processing Society of Japan, Vol. 33, No. 12 (1992) pages 1512-1526. -""" -function TanYam7ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - c1 = convert(T2, 0.07816646510113846) - c2 = convert(T2, 0.1172496976517077) - c3 = convert(T2, 0.17587454647756157) - c4 = convert(T2, 0.4987401101913988) - c5 = convert(T2, 0.772121690184484) - c6 = convert(T2, 0.9911856696047768) - c7 = convert(T2, 0.9995019582097662) - a21 = convert(T, 0.07816646510113846) - a31 = convert(T, 0.029312424412926925) - a32 = convert(T, 0.08793727323878078) - a41 = convert(T, 0.04396863661939039) - a43 = convert(T, 0.13190590985817116) - a51 = convert(T, 0.7361834837738382) - a53 = convert(T, -2.8337999624233303) - a54 = convert(T, 2.5963565888408913) - a61 = convert(T, -12.062819391370866) - a63 = convert(T, 48.20838100175243) - a64 = convert(T, -38.05863046463434) - a65 = convert(T, 2.6851905444372632) - a71 = convert(T, 105.21957276320198) - a73 = convert(T, -417.92888626241256) - a74 = convert(T, 332.3155504499333) - a75 = convert(T, -19.827591183572938) - a76 = convert(T, 1.2125399024549859) - a81 = convert(T, 114.67755718631742) - a83 = convert(T, -455.5612169896097) - a84 = convert(T, 362.24095553923144) - a85 = convert(T, -21.67190442182809) - a86 = convert(T, 1.3189132007137807) - a87 = convert(T, -0.0048025566150346555) - a91 = convert(T, 115.21334870553768) - a93 = convert(T, -457.69356568613233) - a94 = convert(T, 363.93688218862735) - a95 = convert(T, -21.776682078900294) - a96 = convert(T, 1.3250670887878468) - a97 = convert(T, -0.004518190986768983) - a98 = convert(T, -0.0005320269334859959) - a101 = convert(T, 115.18928245800194) - a103 = convert(T, -457.598022271643) - a104 = convert(T, 363.8610256312148) - a105 = convert(T, -21.77212754027556) - a106 = convert(T, 1.3248804645074317) - a107 = convert(T, -0.0045057252106918315) - a108 = convert(T, -0.0005330165949429136) - b1 = convert(T, 0.05126014249744686) - b4 = convert(T, 0.27521638456212627) - b5 = convert(T, 0.33696650340710543) - b6 = convert(T, 0.18986072244906577) - b7 = convert(T, 8.461099418514403) - b8 = convert(T, -130.15941672640542) - b9 = convert(T, 121.84501355497527) - # bhat1 =convert(T,0.051002417590377186) - # bhat4 =convert(T,0.27613929504666546) - # bhat5 =convert(T,0.333788602069686) - # bhat6 =convert(T,0.20196531139081392) - # bhat7 =convert(T,5.755075459041811) - # bhat8 =convert(T,-85.61797108513936) - # bhat10=convert(T,80) - btilde1 = convert(T, -0.0002577249070696835) - btilde4 = convert(T, 0.0009229104845391819) - btilde5 = convert(T, -0.0031779013374194105) - btilde6 = convert(T, 0.01210458894174817) - btilde7 = convert(T, -2.706023959472591) - btilde8 = convert(T, 44.541445641266066) - btilde9 = convert(T, -121.84501355497527) - btilde10 = convert(T, 80) - - TanYam7ConstantCache( - c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, - a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, - a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, - a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, - btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10) -end - -""" -On the Optimization of Some Nine-Stage Seventh-order Runge-Kutta Method, by M. Tanaka, S. Muramatsu and S. Yamashita, -Information Processing Society of Japan, Vol. 33, No. 12 (1992) pages 1512-1526. -""" -function TanYam7ConstantCache(T::Type, T2::Type) - c1 = convert(T2, 36259 // 463869) - c2 = convert(T2, 36259 // 309246) - c3 = convert(T2, 36259 // 206164) - c4 = convert(T2, 76401 // 153188) - c5 = convert(T2, 5164663400901569152 // 6688924124988083687) - c6 = convert(T2, 3486 // 3517) - c7 = convert(T2, 44151 // 44173) - a21 = convert(T, 36259 // 463869) - a31 = convert(T, 36259 // 1236984) - a32 = convert(T, 36259 // 412328) - a41 = convert(T, 36259 // 824656) - a43 = convert(T, 108777 // 824656) - a51 = convert(T, 17751533712975975593187 // 24112920357813127230992) - a53 = convert(T, -68331192803887602162951 // 24112920357813127230992) - a54 = convert(T, 7825717455900471140481 // 3014115044726640903874) - a61 = convert(T, - -BigInt(2425518501234340256175806929031336393991001205323654593685210322030691047097621496102266496) // - BigInt(201073929944556265242953373967503382318096046559546854970564286270157897072030532387737241)) - a63 = convert(T, - BigInt(126875939114499086848675646731069753055308007638565564293214808307459627250976287910912) // - BigInt(2631823273838775215546306644775636213113650954300949659959480717139276934490785884841)) - a64 = convert(T, - -BigInt(18238165682427587123600563411903599919711680222699338744428834349094610403849667513626245575680) // - BigInt(479212348415302218688412787744011607018072627155280851781784515530195350673833210517995172867)) - a65 = convert(T, - BigInt(74777425357290689294313120787550134201356775453356604582280658347816977407509825814840320) // - BigInt(27848089034948481594251542168496834020714916243735255636715495143105044359669539013058107)) - a71 = convert(T, - BigInt(42210784012026021620512889337138957588173072058924928398799062235) // - BigInt(401168555464694196502745570125544252560955194769351196028554688)) - a73 = convert(T, - -BigInt(53537582181289418572806048482253962781541488) // - BigInt(128102133978061070595749084326726258918069)) - a74 = convert(T, - BigInt(6373437319382536771018620806214785516542915567996760353063349991182871200304) // - BigInt(19178871740288180724887392022898914045213833131528843480576173243533301485)) - a75 = convert(T, - -BigInt(836513109281956728811652083904588515347012294160401579661057793958992) // - BigInt(42189346226535262916910956145917457264775063492307360825161811325023)) - a76 = convert(T, - BigInt(10038768138260655813133796321688310283082351149893792474426644227234755871856831386997923013888351) // - BigInt(8279123943002224665888560854425725483235895533066047643118716510648226939201056966728652698557760)) - a81 = convert(T, - BigInt(1454976871505621321312348899226731229297985195430097820532172928754404221419640982320963761) // - BigInt(12687546780768188413911065021432924447284583965992535848754097389537051103097048673168256)) - a83 = convert(T, - -BigInt(1452249436938195913836212549773886207822959770792) // - BigInt(3187825000852340545619892931005470986913487349)) - a84 = convert(T, - BigInt(3193785703967379485471835519262043520640585789136428552340853315619929163223926155626278646291801931779256) // - BigInt(8816743814108800069900425523882492176796603795861854625575345408990649746129323017714575203134405597571)) - a85 = convert(T, - -BigInt(314398569508916946629277462588835135011587938712337655816458752800894863689255534896547161759213480) // - BigInt(14507196201560052990013371105817112064769849230048646555812475120383456376679192045076337148816813)) - a86 = convert(T, - BigInt(5021633516852870452803558794670341128133410978274753232000155240629688617274518068065484524425884625107263111090060721584249881611265924113) // - BigInt(3807402575192378287101053794016079417728266285278436439472658972755893033722804748992796724254152818232996309281540415603729279478920107136)) - a87 = convert(T, - -BigInt(894451839895008223904010765658125850176064186717638397881061173697811879745) // - BigInt(186244934020117483847289332768639722211239803963523669807238114327710091115676)) - a91 = convert(T, - BigInt(152015786770038627019906826956584678402371493198250158080970494807155603994339) // - BigInt(1319428594672311986480108760138089275639618425553698631283119461253421932416)) - a93 = convert(T, - -BigInt(19887569115365707672105043997835466942389220328) // - BigInt(43451712251082409470704235239058276887205131)) - a94 = convert(T, - BigInt(6298831527954572673520838478029639446424615570453903300371170696118960335541193275024146681623960) // - BigInt(17307483347318198085207889427954666589398911583434527253470846782562794571553580157056644256313)) - a95 = convert(T, - -BigInt(16267621644623777942279856217571823792451732234540266142050307930357537283432611648312520) // - BigInt(747020211145282116967827947968990352912884924402891384654470989583659988117513448655559)) - a96 = convert(T, - BigInt(491920517345271821393960134665582163547632868347911487496995665146055538579545277983570189994492481977206720065882583432234119698425636137169515) // - BigInt(371241970695441505578374965290296000309261530083026613438333515399198575394818137422626328203755084156959422247928840402063855870066548878130304)) - a97 = convert(T, - -BigInt(17535891839112183607157943692398769696531153719141528498448224128785868799210475) // - BigInt(3881175428498724209649715816699297677268154716152409333146177577349474565697791732)) - a98 = convert(T, - -BigInt(31140449219386755112730831706895080247696102690585728771850210691242594436100540310) // - BigInt(58531715707220748822628340615174217489020037018063169180406742622693159384762890406389)) - a101 = convert(T, - BigInt(24861126512935523838485032295435745281790804119672244200744512677831357181363) // - BigInt(215828469302253893975010055544246846578750854407392771457340001283636121600)) - a103 = convert(T, -76626859319946149305867456329803 // 167454524692981091214376557800) - a104 = convert(T, - BigInt(257532657386915224604779230484778835596042580268896440943054087972106955277512448850995064336363) // - BigInt(707777528357579864776572552477247532276956780876653359042572831013312547307465249178438602200)) - a105 = convert(T, - -BigInt(103092665221253777021612043042409780416654274677686197534469014507504059634284484983141143) // - BigInt(4735075386204034224907103653335170134874540866215348781137359896717512695961598377363000)) - a106 = convert(T, - BigInt(1318945254307068672853031172410281620677291556423152759282406612372948205789241763483098989903852936890735513699395545618802215742952753372919) // - BigInt(995520191927224509158660659519643916330847017611189618002256023928790665495276022949114110343406997764203331763292012060684160018593393766400)) - a107 = convert(T, - -BigInt(2175691361381933486174620849991740173349017185199505364607841) // - BigInt(482872625303278742130341621563226511344221688759361797916327450)) - a108 = convert(T, - -BigInt(11327601987184122343710458559595782081610122892585097) // - BigInt(21251874884678431935286330856983429378055579208005268000)) - b1 = convert(T, - BigInt(677260699094873524061210073954310211) // - BigInt(13212228177645157882237395248920447488)) - b4 = convert(T, - BigInt(5627843976805934592544586970647029617399366281651959837492864) // - BigInt(20448796992082885248862284273169726631726393791864145954479875)) - b5 = convert(T, - BigInt(1359735671458057021603668186882234273947181034928034734244224) // - BigInt(4035225037829041960922838374222759264846456609494840689395475)) - b6 = convert(T, - BigInt(3575764371063841994042920363615768888383369782579963896064642431626191680598750790399139608006651160426580137040859330533720256407) // - BigInt(18833618269956378326078572170759846509476617594300797062242096554507068838086062412372695473217373611870290738365243380652826304000)) - b7 = convert(T, - BigInt(14322850798205614664394883796805489119964080948503151) // - BigInt(1692788382425178679633337406927131793062126418747780)) - b8 = convert(T, - -BigInt(16735096417960349589058935251250023138290806176584545269411) // - BigInt(128573843052304513208482301684749747737236254208431871400)) - b9 = convert(T, - 33050288141543277444692395096256051 // 271248590133163812341791503489000) - # bhat1 =convert(T,BigInt(962650826879437817605721930727384851)//BigInt(18874611682350225546053421784172067840)) - # bhat4 =convert(T,BigInt(99703652969826806275610089806158069716600653757297413344)//BigInt(361062893830367886445877712954352019629670588714825566425)) - # bhat5 =convert(T,BigInt(17540887447270394964911517553576959050951784592644178144)//BigInt(52550888012671962193116521992300249584518949945887203425)) - # bhat6 =convert(T,BigInt(101855668513773837712956593596043266148479443244790887636953159551191054134940671472736229702711787350735239179)//BigInt(504322587935299170723833764883183242017770187561624249681119708768991642691172146267201689787026963930014131200)) - # bhat7 =convert(T,BigInt(179578338747395946570172802104016572846366090083599)//BigInt(31203472487100067827342625012481692038011546889360)) - # bhat8 =convert(T,-BigInt(500374162579884236288722085953024481890963958534161489781)//BigInt(5844265593286568782203740985670443078965284282201448700)) - # bhat10=convert(T,80) - btilde1 = convert(T, - BigInt(-11350400930890172457349074817136051) // - BigInt(44040760592150526274124650829734824960)) - btilde4 = convert(T, - BigInt(18872409140206580874590465524732661000311743892579167244576) // - BigInt(20448796992082885248862284273169726631726393791864145954479875)) - btilde5 = convert(T, - BigInt(-4274515681501734477669162831906773100582117137555409033632) // - BigInt(1345075012609680653640946124740919754948818869831613563131825)) - btilde6 = convert(T, - BigInt(151982138295746861476872192192436808638630079892291260212523545728864842939698890632387350810275352451114165347163409431707619557) // - BigInt(12555745513304252217385714780506564339651078396200531374828064369671379225390708274915130315478249074580193825576828920435217536000)) - btilde7 = convert(T, - BigInt(-6107634561545846083950679043550120057398294081957207) // - BigInt(2257051176566904906177783209236175724082835224997040)) - btilde8 = convert(T, - BigInt(1908954947067632130235683120094494845563199696277664164743) // - BigInt(42857947684101504402827433894916582579078751402810623800)) - btilde9 = convert(T, - -33050288141543277444692395096256051 // - 271248590133163812341791503489000) - btilde10 = convert(T, 80) - - TanYam7ConstantCache( - c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a53, a54, - a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, - a86, a87, a91, a93, a94, a95, a96, a97, a98, a101, a103, a104, - a105, a106, a107, a108, b1, b4, b5, b6, b7, b8, b9, btilde1, - btilde4, btilde5, btilde6, btilde7, btilde8, btilde9, btilde10) -end - -struct TsitPap8ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - c1::T2 - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - c8::T2 - c9::T2 - c10::T2 - a0201::T - a0301::T - a0302::T - a0401::T - a0403::T - a0501::T - a0503::T - a0504::T - a0601::T - a0604::T - a0605::T - a0701::T - a0704::T - a0705::T - a0706::T - a0801::T - a0804::T - a0805::T - a0806::T - a0807::T - a0901::T - a0904::T - a0905::T - a0906::T - a0907::T - a0908::T - a1001::T - a1004::T - a1005::T - a1006::T - a1007::T - a1008::T - a1009::T - a1101::T - a1104::T - a1105::T - a1106::T - a1107::T - a1108::T - a1109::T - a1110::T - a1201::T - a1204::T - a1205::T - a1206::T - a1207::T - a1208::T - a1209::T - a1210::T - a1211::T - a1301::T - a1304::T - a1305::T - a1306::T - a1307::T - a1308::T - a1309::T - a1310::T - b1::T - b6::T - b7::T - b8::T - b9::T - b10::T - b11::T - b12::T - btilde1::T - btilde6::T - btilde7::T - btilde8::T - btilde9::T - btilde10::T - btilde11::T - btilde12::T - btilde13::T -end - -""" -Cheap Error Estimation for Runge-Kutta methods, by Ch. Tsitouras and S.N. Papakostas, -Siam Journal on Scientific Computing, Vol. 20, Issue 6, Nov 1999. -""" -function TsitPap8ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - c1 = convert(T2, 0.06338028169014084) - c2 = convert(T2, 0.1027879458763643) - c3 = convert(T2, 0.15418191881454646) - c4 = convert(T2, 0.3875968992248062) - c5 = convert(T2, 0.4657534246575342) - c6 = convert(T2, 0.1554054054054054) - c7 = convert(T2, 1.0070921985815602) - c8 = convert(T2, 0.876141078561489) - c9 = convert(T2, 0.9120879120879121) - c10 = convert(T2, 0.959731543624161) - a0201 = convert(T, 0.06338028169014084) - a0301 = convert(T, 0.019438980427336498) - a0302 = convert(T, 0.08334896544902781) - a0401 = convert(T, 0.038545479703636615) - a0403 = convert(T, 0.11563643911090984) - a0501 = convert(T, 0.39436557770112496) - a0503 = convert(T, -1.4818719321673373) - a0504 = convert(T, 1.4751032536910185) - a0601 = convert(T, 0.045994489107698204) - a0604 = convert(T, 0.23235070626395474) - a0605 = convert(T, 0.18740822928588133) - a0701 = convert(T, 0.06005228953244051) - a0704 = convert(T, 0.11220383194636775) - a0705 = convert(T, -0.03357232951906142) - a0706 = convert(T, 0.016721613445658576) - a0801 = convert(T, -1.5733292732086857) - a0804 = convert(T, -1.3167087730223663) - a0805 = convert(T, -11.723515296181773) - a0806 = convert(T, 9.107825028173872) - a0807 = convert(T, 6.512820512820513) - a0901 = convert(T, -0.48107625624391254) - a0904 = convert(T, -6.6506103607463904) - a0905 = convert(T, -4.530206099782572) - a0906 = convert(T, 3.894414525020157) - a0907 = convert(T, 8.634217645525526) - a0908 = convert(T, 0.009401624788681498) - a1001 = convert(T, -0.7754121446230569) - a1004 = convert(T, -7.996604718235832) - a1005 = convert(T, -6.726558607230182) - a1006 = convert(T, 5.532184454327406) - a1007 = convert(T, 10.89757332024991) - a1008 = convert(T, 0.020091650280045396) - a1009 = convert(T, -0.039186042680376856) - a1101 = convert(T, -1.1896363245449992) - a1104 = convert(T, -7.128368483301214) - a1105 = convert(T, -9.53722789710108) - a1106 = convert(T, 7.574470108980868) - a1107 = convert(T, 11.267486382070919) - a1108 = convert(T, 0.051009801223058315) - a1109 = convert(T, 0.08019413469508256) - a1110 = convert(T, -0.15819617839847347) - a1201 = convert(T, -0.39200039047127266) - a1204 = convert(T, 3.916659042493856) - a1205 = convert(T, -2.8017459289080557) - a1206 = convert(T, 2.441204566481742) - a1207 = convert(T, -2.4183655778824718) - a1208 = convert(T, -0.33943326290032927) - a1209 = convert(T, 0.19496450383103364) - a1210 = convert(T, -0.19437176762508154) - a1211 = convert(T, 0.5930888149805791) - a1301 = convert(T, -1.4847063081291894) - a1304 = convert(T, -2.390723588981498) - a1305 = convert(T, -11.184306772840532) - a1306 = convert(T, 8.720804667459817) - a1307 = convert(T, 7.33673830753461) - a1308 = convert(T, 0.01289874999394761) - a1309 = convert(T, 0.042583289842657704) - a1310 = convert(T, -0.05328834487981156) - b1 = convert(T, 0.04441161093250152) - b6 = convert(T, 0.35395063113733116) - b7 = convert(T, 0.2485219684184965) - b8 = convert(T, -0.3326913171720666) - b9 = convert(T, 1.921248828652836) - b10 = convert(T, -2.7317783000882523) - b11 = convert(T, 1.4012004409899175) - b12 = convert(T, 0.0951361371292365) - # bhat1 =convert(T,0.044484201850329544) - # bhat6 =convert(T,0.35502352274458154) - # bhat7 =convert(T,0.24825530158391707) - # bhat8 =convert(T,-2.4242252962684616) - # bhat9 =convert(T,1.5999301534099692) - # bhat10=convert(T,-1.8107646286929684) - # bhat13=convert(T,2.9872967453726327) - btilde1 = convert(T, -7.259091782802626e-5) - btilde6 = convert(T, -0.0010728916072503584) - btilde7 = convert(T, 0.0002666668345794398) - btilde8 = convert(T, 2.091533979096395) - btilde9 = convert(T, 0.3213186752428666) - btilde10 = convert(T, -0.921013671395284) - btilde11 = convert(T, 1.4012004409899175) - btilde12 = convert(T, 0.0951361371292365) - btilde13 = convert(T, -2.9872967453726327) - - TsitPap8ConstantCache(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, - a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, - a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, - a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, - a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, - a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, - a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, - a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, - btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13) -end - -""" -Cheap Error Estimation for Runge-Kutta methods, by Ch. Tsitouras and S.N. Papakostas, -Siam Journal on Scientific Computing, Vol. 20, Issue 6, Nov 1999. -""" -function TsitPap8ConstantCache(T::Type, T2::Type) - c1 = convert(T2, 9 // 142) - c2 = convert(T2, 24514 // 238491) - c3 = convert(T2, 12257 // 79497) - c4 = convert(T2, 50 // 129) - c5 = convert(T2, 34 // 73) - c6 = convert(T2, 23 // 148) - c7 = convert(T2, 142 // 141) - c8 = convert(T2, 29104120198 // 33218531707) - c9 = convert(T2, 83 // 91) - c10 = convert(T2, 143 // 149) - a0201 = convert(T, 9 // 142) - a0301 = convert(T, 9950845450 // 511901613729) - a0302 = convert(T, 42666469916 // 511901613729) - a0401 = convert(T, 12257 // 317988) - a0403 = convert(T, 12257 // 105996) - a0501 = convert(T, 14131686489425 // 35833975601529) - a0503 = convert(T, -17700454220625 // 11944658533843) - a0504 = convert(T, 17619604667500 // 11944658533843) - a0601 = convert(T, 4418011 // 96055225) - a0604 = convert(T, 9757757988 // 41995818067) - a0605 = convert(T, 19921512441 // 106300094275) - a0701 = convert(T, 480285555889619 // 7997789253816320) - a0704 = convert(T, 52162106556696460538643 // 464887033284472899365888) - a0705 = convert(T, -16450769949384489 // 490009784398315520) - a0706 = convert(T, 864813381633887 // 51718297665732608) - a0801 = convert(T, -7001048352088587137143 // 4449830351030385148800) - a0804 = convert(T, -2522765548294599044197935933 // 1915963195493758447677901792) - a0805 = convert(T, -318556182235222634647116091 // 27172411532484037214054400) - a0806 = convert(T, 1205563885850790193966807 // 132365727505912221222912) - a0807 = convert(T, 254 // 39) - a0901 = convert(T, - -BigInt(20629396399716689122801179264428539394462855874226604463554767070845753369) // - BigInt(42881759662770155956657513470012114488076017981128105307375594963152353200)) - a0904 = convert(T, - -BigInt(3315443074343659404779422149387397712986453181141168247590906370819301077749322753) // - BigInt(498517112641608872807821838566847987729514312398278633788185835348997643218553476)) - a0905 = convert(T, - -BigInt(273749409411654060286948141164828452109898379203526945684314474186724062841643) // - BigInt(60427583951377552503967840653825589117167443021628367691773162913607984889600)) - a0906 = convert(T, - BigInt(16656372518874512738268060504309924900437672263609245028809229865738327731797537) // - BigInt(4276990138533930522782076385771016009097627930550149628282203007913538394549504)) - a0907 = convert(T, - BigInt(42008080033354305590804322944084805264441066760038302359736803632) // - BigInt(4865302423216534910074823287811605599629170295030631799935804001)) - a0908 = convert(T, - BigInt(668459780930716338000066627236927417191947396177093524377824) // - BigInt(71100452948884643779799087713322002499799983434685642170251833)) - a1001 = convert(T, - -BigInt(1793603946322260900828212460706877142477132870159527) // - BigInt(2313097568511990753781649719556084665131024900300800)) - a1004 = convert(T, - -BigInt(14776874123722838192315406145167687512425345723701) // - BigInt(1847893530366076701102014146927696206329050105856)) - a1005 = convert(T, - -BigInt(19587020919884661714856757105130246995757906603) // - BigInt(2911893296942532038566182868170393629789388800)) - a1006 = convert(T, - BigInt(6364380863259071677112259236455506477417699780613300364807) // - BigInt(1150428174584942133406579091549443438814988349188394057728)) - a1007 = convert(T, - BigInt(27725164402569748756040320433848245155581006369) // - BigInt(2544159473655547770881695354241256106302348256)) - a1008 = convert(T, - BigInt(10744247163960019876833255044784609639) // - BigInt(534761804739901348825491947768304503296)) - a1009 = convert(T, - -BigInt(50977737930792808232204417497248979399878217280011103197862899) // - BigInt(1300915694564913675613280314081837358644964393191337994183389184)) - a1101 = convert(T, - -BigInt(3587625717068952487214493441966897048737050755812600710793) // - BigInt(3015733164033229624772006086429467685046639983706974412800)) - a1104 = convert(T, - -BigInt(5453011711267804731211501837262816944661201619903) // - BigInt(764973320899716397072448644710733101329290196992)) - a1105 = convert(T, - -BigInt(884348836774584715070440485633026464653487653) // - BigInt(92725983515963799584249219499787659014963200)) - a1106 = convert(T, - BigInt(26823469063654084387375587616552322383082061411417182757389742951) // - BigInt(3541299744763681675473620647087123057228744296123642301654630400)) - a1107 = convert(T, - BigInt(142363419491686507162007051071007722765323162710521029) // - BigInt(12634887202368261565807449771335728082273587905775840)) - a1108 = convert(T, - BigInt(64747617454909275289531520412519442831235890581) // - BigInt(1269317188117975960996670628974453443777854830080)) - a1109 = convert(T, - BigInt(112633808253272720979874303367503891597499261046700689572459050065039333987335667) // - BigInt(1404514291245034532812181377119034501014039830518218465064579291611563374608650240)) - a1110 = convert(T, - -BigInt(10612202518573994431153697720606405883) // - BigInt(67082546658259846778754594976831647575)) - a1201 = convert(T, - -BigInt(7534081165544982478296202335922049210803875045423) // - BigInt(19219575665440848756074598051658416387002479820800)) - a1204 = convert(T, - BigInt(237696087452786717802270375283034262859273455) // - BigInt(60688480889936839261131818793519097177034752)) - a1205 = convert(T, - -BigInt(20610578209826329263318986584876108069323) // - BigInt(7356333776438834884293014575840932659200)) - a1206 = convert(T, - BigInt(51260471529841028040709654458903254781320136131844164563) // - BigInt(20998023776318546907382302106788168158765514131585630208)) - a1207 = convert(T, - -BigInt(3077214437173472971196810795615384000211457151011) // - BigInt(1272435592582280820597059432060116893200684680384)) - a1208 = convert(T, - -BigInt(1539218116260541896259682954580256454049) // - BigInt(4534670830750360983422999946409310393344)) - a1209 = convert(T, - BigInt(241886539350268429372116296787271276553970618941104594460614948326132797451456131) // - BigInt(1240669632662465892528916120041123051054026283188324780101555345343662316090597376)) - a1210 = convert(T, - -80556486832245966191717452425924975 // - 414445409518676597565032008051106461) - a1211 = convert(T, - BigInt(2944781680874500347594142792814463350) // - BigInt(4965161383073676983610218096030654529)) - a1301 = convert(T, - -BigInt(7757739937862944832927743694336116203639371542761) // - BigInt(5225100678421794325654850845451340473577260032000)) - a1304 = convert(T, - -BigInt(433889546009521405913741133329446636837810749) // - BigInt(181488796115643001621310691169322233346938880)) - a1305 = convert(T, - -BigInt(246044720162308748108107126829066792329071) // - BigInt(21999103311417807170100413255475150848000)) - a1306 = convert(T, - BigInt(2140331235425829844389060818616719848637810765257179167) // - BigInt(245428182036011897638028252815369258646052549878743040)) - a1307 = convert(T, - BigInt(1573990926219809229258666534611598771063240529) // - BigInt(214535514317495538101650508596881057760818080)) - a1308 = convert(T, - BigInt(62408280667309375445301959066100433563) // - BigInt(4838320046251983849512355559327451645440)) - a1309 = convert(T, - BigInt(1145609822249493677618113725359506642998153205603226883141207089968379) // - BigInt(26902802166822768476367427840835743139559294105398677975568538466119680)) - a1310 = convert(T, - -408950356875874683139089678053832 // - 7674292714443204070455739595109785) - b1 = convert(T, 55038446513529253801 // 1239280570055853383520) - b6 = convert(T, 2335496795323782464411846394611 // 6598368783294020109895379936256) - b7 = convert(T, 7636073376527143565375240869888 // 30725949199261296642046754748645) - b8 = convert(T, -4237087214169934312729607487 // 12735791394214625116604076160) - b9 = convert(T, - BigInt(408505291291133241760995514121984335914363927884426780078325258228227984174126699) // - BigInt(212624874612193697466655159405635202123821166475348052734199905546455860773575680)) - b10 = convert(T, -1108225296327029096435947 // 405679075893979729103310) - b11 = convert(T, 2460988291206213825688467985 // 1756342789520947764222671739) - b12 = convert(T, 4808707937311 // 50545545388065) - # bhat1 =convert(T,715953338020208413//16094552857868225760) - # bhat6 =convert(T,62284335162928966987066121//175437206755843240272669696) - # bhat7 =convert(T,184309146777472302831695872//742417767522160213324368465) - # bhat8 =convert(T,-509771598215811385123057257//210282269969085698264101760) - # bhat9 =convert(T,BigInt(2701602489646143640362891402924962500766379885231830470264478480621389)//BigInt(1688575269294196295712420798364925687791337062814161130291144634516480)) - # bhat10=convert(T,-7218534073012286740367561//3986456306153224954098780) - # bhat13=convert(T,5752173075461//1925544586212) - btilde1 = convert(T, -1124506425334925 // 15491007125698167294) - btilde6 = convert(T, -34035261967014004512968665 // 31722926842759712066804711232) - btilde7 = convert(T, 24580774837247048845194838016 // 92177847597783889926140264245935) - btilde8 = convert(T, 7658235379858959628545472335 // 3661540025836704721023671896) - btilde9 = convert(T, - BigInt(1510930663253486646384296195586886863633653147150681174690536256975353069486325) // - BigInt(4702280880846591386281796794547701585430660412435581935467882526508158459415616)) - btilde10 = convert(T, -237184116991804346989794715 // 257525077377498332034781188) - btilde11 = convert(T, 2460988291206213825688467985 // 1756342789520947764222671739) - btilde12 = convert(T, 4808707937311 // 50545545388065) - btilde13 = convert(T, -5752173075461 // 1925544586212) - - TsitPap8ConstantCache(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, a0201, a0301, a0302, - a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, - a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, - a0904, a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, - a1007, a1008, a1009, a1101, a1104, a1105, a1106, a1107, a1108, - a1109, a1110, a1201, a1204, a1205, a1206, a1207, a1208, a1209, - a1210, a1211, a1301, a1304, a1305, a1306, a1307, a1308, a1309, - a1310, b1, b6, b7, b8, b9, b10, b11, b12, btilde1, btilde6, - btilde7, btilde8, btilde9, btilde10, btilde11, btilde12, btilde13) -end - -struct DP8ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - c7::T2 - c8::T2 - c9::T2 - c10::T2 - c11::T2 - c6::T2 - c5::T2 - c4::T2 - c3::T2 - c2::T2 - b1::T - b6::T - b7::T - b8::T - b9::T - b10::T - b11::T - b12::T - btilde1::T - btilde6::T - btilde7::T - btilde8::T - btilde9::T - btilde10::T - btilde11::T - btilde12::T - er1::T - er6::T - er7::T - er8::T - er9::T - er10::T - er11::T - er12::T - a0201::T - a0301::T - a0302::T - a0401::T - a0403::T - a0501::T - a0503::T - a0504::T - a0601::T - a0604::T - a0605::T - a0701::T - a0704::T - a0705::T - a0706::T - a0801::T - a0804::T - a0805::T - a0806::T - a0807::T - a0901::T - a0904::T - a0905::T - a0906::T - a0907::T - a0908::T - a1001::T - a1004::T - a1005::T - a1006::T - a1007::T - a1008::T - a1009::T - a1101::T - a1104::T - a1105::T - a1106::T - a1107::T - a1108::T - a1109::T - a1110::T - a1201::T - a1204::T - a1205::T - a1206::T - a1207::T - a1208::T - a1209::T - a1210::T - a1211::T - c14::T2 - c15::T2 - c16::T2 - a1401::T - a1407::T - a1408::T - a1409::T - a1410::T - a1411::T - a1412::T - a1413::T - a1501::T - a1506::T - a1507::T - a1508::T - a1511::T - a1512::T - a1513::T - a1514::T - a1601::T - a1606::T - a1607::T - a1608::T - a1609::T - a1613::T - a1614::T - a1615::T - d401::T - d406::T - d407::T - d408::T - d409::T - d410::T - d411::T - d412::T - d413::T - d414::T - d415::T - d416::T - d501::T - d506::T - d507::T - d508::T - d509::T - d510::T - d511::T - d512::T - d513::T - d514::T - d515::T - d516::T - d601::T - d606::T - d607::T - d608::T - d609::T - d610::T - d611::T - d612::T - d613::T - d614::T - d615::T - d616::T - d701::T - d706::T - d707::T - d708::T - d709::T - d710::T - d711::T - d712::T - d713::T - d714::T - d715::T - d716::T -end - -function DP8ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - c7 = convert(T2, 0.25) - c8 = convert(T2, 0.3076923076923077) - c9 = convert(T2, 0.6512820512820513) - c10 = convert(T2, 0.6) - c11 = convert(T2, 0.8571428571428571) - c6 = convert(T2, 0.3333333333333333) - c5 = convert(T2, 0.2816496580927726) - c4 = convert(T2, 0.1183503419072274) - c3 = convert(T2, 0.0789002279381516) - c2 = convert(T2, 0.05260015195876773) - b1 = convert(T, 0.054293734116568765) - b6 = convert(T, 4.450312892752409) - b7 = convert(T, 1.8915178993145003) - b8 = convert(T, -5.801203960010585) - b9 = convert(T, 0.3111643669578199) - b10 = convert(T, -0.1521609496625161) - b11 = convert(T, 0.20136540080403034) - b12 = convert(T, 0.04471061572777259) - # bhh1 = convert(T,0.2440944881889764) - # bhh2 = convert(T,0.7338466882816118) - # bhh3 = convert(T,0.022058823529411766) - btilde1 = convert(T, -0.18980075407240762) - btilde6 = convert(T, 4.450312892752409) - btilde7 = convert(T, 1.8915178993145003) - btilde8 = convert(T, -5.801203960010585) - btilde9 = convert(T, -0.42268232132379197) - btilde10 = convert(T, -0.1521609496625161) - btilde11 = convert(T, 0.20136540080403034) - btilde12 = convert(T, 0.022651792198360825) - er1 = convert(T, 0.01312004499419488) - er6 = convert(T, -1.2251564463762044) - er7 = convert(T, -0.4957589496572502) - er8 = convert(T, 1.6643771824549864) - er9 = convert(T, -0.35032884874997366) - er10 = convert(T, 0.3341791187130175) - er11 = convert(T, 0.08192320648511571) - er12 = convert(T, -0.022355307863886294) - a0201 = convert(T, 0.05260015195876773) - a0301 = convert(T, 0.0197250569845379) - a0302 = convert(T, 0.0591751709536137) - a0401 = convert(T, 0.02958758547680685) - a0403 = convert(T, 0.08876275643042054) - a0501 = convert(T, 0.2413651341592667) - a0503 = convert(T, -0.8845494793282861) - a0504 = convert(T, 0.924834003261792) - a0601 = convert(T, 0.037037037037037035) - a0604 = convert(T, 0.17082860872947386) - a0605 = convert(T, 0.12546768756682242) - a0701 = convert(T, 0.037109375) - a0704 = convert(T, 0.17025221101954405) - a0705 = convert(T, 0.06021653898045596) - a0706 = convert(T, -0.017578125) - a0801 = convert(T, 0.03709200011850479) - a0804 = convert(T, 0.17038392571223998) - a0805 = convert(T, 0.10726203044637328) - a0806 = convert(T, -0.015319437748624402) - a0807 = convert(T, 0.008273789163814023) - a0901 = convert(T, 0.6241109587160757) - a0904 = convert(T, -3.3608926294469414) - a0905 = convert(T, -0.868219346841726) - a0906 = convert(T, 27.59209969944671) - a0907 = convert(T, 20.154067550477894) - a0908 = convert(T, -43.48988418106996) - a1001 = convert(T, 0.47766253643826434) - a1004 = convert(T, -2.4881146199716677) - a1005 = convert(T, -0.590290826836843) - a1006 = convert(T, 21.230051448181193) - a1007 = convert(T, 15.279233632882423) - a1008 = convert(T, -33.28821096898486) - a1009 = convert(T, -0.020331201708508627) - a1101 = convert(T, -0.9371424300859873) - a1104 = convert(T, 5.186372428844064) - a1105 = convert(T, 1.0914373489967295) - a1106 = convert(T, -8.149787010746927) - a1107 = convert(T, -18.52006565999696) - a1108 = convert(T, 22.739487099350505) - a1109 = convert(T, 2.4936055526796523) - a1110 = convert(T, -3.0467644718982196) - a1201 = convert(T, 2.273310147516538) - a1204 = convert(T, -10.53449546673725) - a1205 = convert(T, -2.0008720582248625) - a1206 = convert(T, -17.9589318631188) - a1207 = convert(T, 27.94888452941996) - a1208 = convert(T, -2.8589982771350235) - a1209 = convert(T, -8.87285693353063) - a1210 = convert(T, 12.360567175794303) - a1211 = convert(T, 0.6433927460157636) - c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = DP8Interp( - T, - T2) - d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = DP8Interp_polyweights(T) - DP8ConstantCache( - c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, - b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, - btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, - a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, - a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, - a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, - a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, - a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, c14, c15, c16, - a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, - a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, - a1609, a1613, a1614, a1615, d401, d406, d407, d408, d409, d410, d411, - d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, - d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, - d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, - d712, d713, d714, d715, d716) -end - -function DP8ConstantCache(T::Type, T2::Type) - c7 = convert(T2, 1 // 4) - c8 = convert(T2, 4 // 13) - c9 = convert(T2, 127 // 195) - c10 = convert(T2, 3 // 5) - c11 = convert(T2, 6 // 7) - c6 = convert(T2, 4 // 3 * c7) - c5 = convert(T2, (6 + sqrt(6)) / 10 * c6) - c4 = convert(T2, (6 - sqrt(6)) / 10 * c6) - c3 = convert(T2, 2 // 3 * c4) - c2 = convert(T2, 2 // 3 * c3) - b1 = convert(T, big" 5.42937341165687622380535766363e-2") - b6 = convert(T, big" 4.45031289275240888144113950566") - b7 = convert(T, big" 1.89151789931450038304281599044") - b8 = convert(T, big"-5.8012039600105847814672114227") - b9 = convert(T, big" 3.1116436695781989440891606237e-1") - b10 = convert(T, big"-1.52160949662516078556178806805e-1") - b11 = convert(T, big" 2.01365400804030348374776537501e-1") - b12 = convert(T, big" 4.47106157277725905176885569043e-2") - # bhh1 = convert(T,big"0.244094488188976377952755905512") - # bhh2 = convert(T,big"0.733846688281611857341361741547") - # bhh3 = convert(T,big"0.220588235294117647058823529412e-01") - btilde1 = convert(T, big"-1.898007540724076157147023288757e-1") - btilde6 = convert(T, big" 4.45031289275240888144113950566") - btilde7 = convert(T, big" 1.89151789931450038304281599044") - btilde8 = convert(T, big"-5.8012039600105847814672114227") - btilde9 = convert(T, big"-4.22682321323791962932445679177e-1") - btilde10 = convert(T, big"-1.52160949662516078556178806805e-1") - btilde11 = convert(T, big" 2.01365400804030348374776537501e-1") - btilde12 = convert(T, big"2.26517921983608258118062039631e-2") - er1 = convert(T, big" 0.1312004499419488073250102996e-01") - er6 = convert(T, big"-0.1225156446376204440720569753e+01") - er7 = convert(T, big"-0.4957589496572501915214079952") - er8 = convert(T, big" 0.1664377182454986536961530415e+01") - er9 = convert(T, big"-0.3503288487499736816886487290") - er10 = convert(T, big" 0.3341791187130174790297318841") - er11 = convert(T, big" 0.8192320648511571246570742613e-01") - er12 = convert(T, big"-0.2235530786388629525884427845e-01") - a0201 = convert(T, big" 5.26001519587677318785587544488e-2") - a0301 = convert(T, big" 1.97250569845378994544595329183e-2") - a0302 = convert(T, big" 5.91751709536136983633785987549e-2") - a0401 = convert(T, big" 2.95875854768068491816892993775e-2") - a0403 = convert(T, big" 8.87627564304205475450678981324e-2") - a0501 = convert(T, big" 2.41365134159266685502369798665e-1") - a0503 = convert(T, big"-8.84549479328286085344864962717e-1") - a0504 = convert(T, big" 9.24834003261792003115737966543e-1") - a0601 = convert(T, big" 3.7037037037037037037037037037e-2") - a0604 = convert(T, big" 1.70828608729473871279604482173e-1") - a0605 = convert(T, big" 1.25467687566822425016691814123e-1") - a0701 = convert(T, big" 3.7109375e-2") - a0704 = convert(T, big" 1.70252211019544039314978060272e-1") - a0705 = convert(T, big" 6.02165389804559606850219397283e-2") - a0706 = convert(T, big"-1.7578125e-2") - a0801 = convert(T, big" 3.70920001185047927108779319836e-2") - a0804 = convert(T, big" 1.70383925712239993810214054705e-1") - a0805 = convert(T, big" 1.07262030446373284651809199168e-1") - a0806 = convert(T, big"-1.53194377486244017527936158236e-2") - a0807 = convert(T, big" 8.27378916381402288758473766002e-3") - a0901 = convert(T, big" 6.24110958716075717114429577812e-1") - a0904 = convert(T, big"-3.36089262944694129406857109825") - a0905 = convert(T, big"-8.68219346841726006818189891453e-1") - a0906 = convert(T, big" 2.75920996994467083049415600797e1") - a0907 = convert(T, big" 2.01540675504778934086186788979e1") - a0908 = convert(T, big"-4.34898841810699588477366255144e1") - a1001 = convert(T, big" 4.77662536438264365890433908527e-1") - a1004 = convert(T, big"-2.48811461997166764192642586468e0") - a1005 = convert(T, big"-5.90290826836842996371446475743e-1") - a1006 = convert(T, big" 2.12300514481811942347288949897e1") - a1007 = convert(T, big" 1.52792336328824235832596922938e1") - a1008 = convert(T, big"-3.32882109689848629194453265587e1") - a1009 = convert(T, big"-2.03312017085086261358222928593e-2") - a1101 = convert(T, big"-9.3714243008598732571704021658e-1") - a1104 = convert(T, big" 5.18637242884406370830023853209e0") - a1105 = convert(T, big" 1.09143734899672957818500254654e0") - a1106 = convert(T, big"-8.14978701074692612513997267357e0") - a1107 = convert(T, big"-1.85200656599969598641566180701e1") - a1108 = convert(T, big" 2.27394870993505042818970056734e1") - a1109 = convert(T, big" 2.49360555267965238987089396762e0") - a1110 = convert(T, big"-3.0467644718982195003823669022e0") - a1201 = convert(T, big" 2.27331014751653820792359768449e0") - a1204 = convert(T, big" -1.05344954667372501984066689879e1") - a1205 = convert(T, big" -2.00087205822486249909675718444e0") - a1206 = convert(T, big" -1.79589318631187989172765950534e1") - a1207 = convert(T, big" 2.79488845294199600508499808837e1") - a1208 = convert(T, big" -2.85899827713502369474065508674e0") - a1209 = convert(T, big" -8.87285693353062954433549289258e0") - a1210 = convert(T, big" 1.23605671757943030647266201528e1") - a1211 = convert(T, big" 6.43392746015763530355970484046e-1") - c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, a1609, a1613, a1614, a1615 = DP8Interp( - T, - T2) - d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, d712, d713, d714, d715, d716 = DP8Interp_polyweights(T) - DP8ConstantCache( - c7, c8, c9, c10, c11, c6, c5, c4, c3, c2, b1, b6, b7, b8, b9, b10, b11, - b12, btilde1, btilde6, btilde7, btilde8, btilde9, btilde10, btilde11, - btilde12, er1, er6, er7, er8, er9, er10, er11, er12, a0201, a0301, - a0302, a0401, a0403, a0501, a0503, a0504, a0601, a0604, a0605, a0701, - a0704, a0705, a0706, a0801, a0804, a0805, a0806, a0807, a0901, a0904, - a0905, a0906, a0907, a0908, a1001, a1004, a1005, a1006, a1007, a1008, - a1009, a1101, a1104, a1105, a1106, a1107, a1108, a1109, a1110, a1201, - a1204, a1205, a1206, a1207, a1208, a1209, a1210, a1211, c14, c15, c16, - a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, a1506, - a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, - a1609, a1613, a1614, a1615, d401, d406, d407, d408, d409, d410, d411, - d412, d413, d414, d415, d416, d501, d506, d507, d508, d509, d510, d511, - d512, d513, d514, d515, d516, d601, d606, d607, d608, d609, d610, d611, - d612, d613, d614, d615, d616, d701, d706, d707, d708, d709, d710, d711, - d712, d713, d714, d715, d716) -end - -function DP8Interp(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - c14 = convert(T2, 0.1) - c15 = convert(T2, 0.2) - c16 = convert(T2, 0.7777777777777778) - a1401 = convert(T, 0.056167502283047954) - a1407 = convert(T, 0.25350021021662483) - a1408 = convert(T, -0.2462390374708025) - a1409 = convert(T, -0.12419142326381637) - a1410 = convert(T, 0.15329179827876568) - a1411 = convert(T, 0.00820105229563469) - a1412 = convert(T, 0.007567897660545699) - a1413 = convert(T, -0.008298) - a1501 = convert(T, 0.03183464816350214) - a1506 = convert(T, 0.028300909672366776) - a1507 = convert(T, 0.053541988307438566) - a1508 = convert(T, -0.05492374857139099) - a1511 = convert(T, -0.00010834732869724932) - a1512 = convert(T, 0.0003825710908356584) - a1513 = convert(T, -0.00034046500868740456) - a1514 = convert(T, 0.1413124436746325) - a1601 = convert(T, -0.42889630158379194) - a1606 = convert(T, -4.697621415361164) - a1607 = convert(T, 7.683421196062599) - a1608 = convert(T, 4.06898981839711) - a1609 = convert(T, 0.3567271874552811) - a1613 = convert(T, -0.0013990241651590145) - a1614 = convert(T, 2.9475147891527724) - a1615 = convert(T, -9.15095847217987) - - return c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, - a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, - a1609, a1613, a1614, a1615 -end - -function DP8Interp(T::Type, T2::Type) - c14 = convert(T2, 1 // 10) - c15 = convert(T2, 2 // 10) - c16 = convert(T2, 7 // 9) - a1401 = convert(T, big" 5.61675022830479523392909219681e-2") - a1407 = convert(T, big" 2.53500210216624811088794765333e-1") - a1408 = convert(T, big"-2.46239037470802489917441475441e-1") - a1409 = convert(T, big"-1.24191423263816360469010140626e-1") - a1410 = convert(T, big" 1.5329179827876569731206322685e-1") - a1411 = convert(T, big" 8.20105229563468988491666602057e-3") - a1412 = convert(T, big" 7.56789766054569976138603589584e-3") - a1413 = convert(T, big"-8.298e-3") - a1501 = convert(T, big" 3.18346481635021405060768473261e-2") - a1506 = convert(T, big" 2.83009096723667755288322961402e-2") - a1507 = convert(T, big" 5.35419883074385676223797384372e-2") - a1508 = convert(T, big"-5.49237485713909884646569340306e-2") - a1511 = convert(T, big"-1.08347328697249322858509316994e-4") - a1512 = convert(T, big" 3.82571090835658412954920192323e-4") - a1513 = convert(T, big"-3.40465008687404560802977114492e-4") - a1514 = convert(T, big" 1.41312443674632500278074618366e-1") - a1601 = convert(T, big"-4.28896301583791923408573538692e-1") - a1606 = convert(T, big"-4.69762141536116384314449447206e0") - a1607 = convert(T, big" 7.68342119606259904184240953878e0") - a1608 = convert(T, big" 4.06898981839711007970213554331e0") - a1609 = convert(T, big" 3.56727187455281109270669543021e-1") - a1613 = convert(T, big"-1.39902416515901462129418009734e-3") - a1614 = convert(T, big" 2.9475147891527723389556272149e0") - a1615 = convert(T, big"-9.15095847217987001081870187138e0") - - return c14, c15, c16, a1401, a1407, a1408, a1409, a1410, a1411, a1412, a1413, a1501, - a1506, a1507, a1508, a1511, a1512, a1513, a1514, a1601, a1606, a1607, a1608, - a1609, a1613, a1614, a1615 -end - -function DP8Interp_polyweights(T::Type{<:CompiledFloats}) - d401 = convert(T, -8.428938276109013) - d406 = convert(T, 0.5667149535193777) - d407 = convert(T, -3.0689499459498917) - d408 = convert(T, 2.38466765651207) - d409 = convert(T, 2.117034582445028) - d410 = convert(T, -0.871391583777973) - d411 = convert(T, 2.2404374302607883) - d412 = convert(T, 0.6315787787694688) - d413 = convert(T, -0.08899033645133331) - d414 = convert(T, 18.148505520854727) - d415 = convert(T, -9.194632392478356) - d416 = convert(T, -4.436036387594894) - d501 = convert(T, 10.427508642579134) - d506 = convert(T, 242.28349177525817) - d507 = convert(T, 165.20045171727028) - d508 = convert(T, -374.5467547226902) - d509 = convert(T, -22.113666853125306) - d510 = convert(T, 7.733432668472264) - d511 = convert(T, -30.674084731089398) - d512 = convert(T, -9.332130526430229) - d513 = convert(T, 15.697238121770845) - d514 = convert(T, -31.139403219565178) - d515 = convert(T, -9.35292435884448) - d516 = convert(T, 35.81684148639408) - d601 = convert(T, 19.985053242002433) - d606 = convert(T, -387.0373087493518) - d607 = convert(T, -189.17813819516758) - d608 = convert(T, 527.8081592054236) - d609 = convert(T, -11.57390253995963) - d610 = convert(T, 6.8812326946963) - d611 = convert(T, -1.0006050966910838) - d612 = convert(T, 0.7777137798053443) - d613 = convert(T, -2.778205752353508) - d614 = convert(T, -60.19669523126412) - d615 = convert(T, 84.32040550667716) - d616 = convert(T, 11.99229113618279) - d701 = convert(T, -25.69393346270375) - d706 = convert(T, -154.18974869023643) - d707 = convert(T, -231.5293791760455) - d708 = convert(T, 357.6391179106141) - d709 = convert(T, 93.40532418362432) - d710 = convert(T, -37.45832313645163) - d711 = convert(T, 104.0996495089623) - d712 = convert(T, 29.8402934266605) - d713 = convert(T, -43.53345659001114) - d714 = convert(T, 96.32455395918828) - d715 = convert(T, -39.17726167561544) - d716 = convert(T, -149.72683625798564) - - return d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, - d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, - d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, - d708, d709, d710, d711, d712, d713, d714, d715, d716 -end - -function DP8Interp_polyweights(T::Type) - d401 = convert(T, big"-0.84289382761090128651353491142e+01") - d406 = convert(T, big" 0.56671495351937776962531783590e+00") - d407 = convert(T, big"-0.30689499459498916912797304727e+01") - d408 = convert(T, big" 0.23846676565120698287728149680e+01") - d409 = convert(T, big" 0.21170345824450282767155149946e+01") - d410 = convert(T, big"-0.87139158377797299206789907490e+00") - d411 = convert(T, big" 0.22404374302607882758541771650e+01") - d412 = convert(T, big" 0.63157877876946881815570249290e+00") - d413 = convert(T, big"-0.88990336451333310820698117400e-01") - d414 = convert(T, big" 0.18148505520854727256656404962e+02") - d415 = convert(T, big"-0.91946323924783554000451984436e+01") - d416 = convert(T, big"-0.44360363875948939664310572000e+01") - d501 = convert(T, big" 0.10427508642579134603413151009e+02") - d506 = convert(T, big" 0.24228349177525818288430175319e+03") - d507 = convert(T, big" 0.16520045171727028198505394887e+03") - d508 = convert(T, big"-0.37454675472269020279518312152e+03") - d509 = convert(T, big"-0.22113666853125306036270938578e+02") - d510 = convert(T, big" 0.77334326684722638389603898808e+01") - d511 = convert(T, big"-0.30674084731089398182061213626e+02") - d512 = convert(T, big"-0.93321305264302278729567221706e+01") - d513 = convert(T, big" 0.15697238121770843886131091075e+02") - d514 = convert(T, big"-0.31139403219565177677282850411e+02") - d515 = convert(T, big"-0.93529243588444783865713862664e+01") - d516 = convert(T, big" 0.35816841486394083752465898540e+02") - d601 = convert(T, big" 0.19985053242002433820987653617e+02") - d606 = convert(T, big"-0.38703730874935176555105901742e+03") - d607 = convert(T, big"-0.18917813819516756882830838328e+03") - d608 = convert(T, big" 0.52780815920542364900561016686e+03") - d609 = convert(T, big"-0.11573902539959630126141871134e+02") - d610 = convert(T, big" 0.68812326946963000169666922661e+01") - d611 = convert(T, big"-0.10006050966910838403183860980e+01") - d612 = convert(T, big" 0.77771377980534432092869265740e+00") - d613 = convert(T, big"-0.27782057523535084065932004339e+01") - d614 = convert(T, big"-0.60196695231264120758267380846e+02") - d615 = convert(T, big" 0.84320405506677161018159903784e+02") - d616 = convert(T, big" 0.11992291136182789328035130030e+02") - d701 = convert(T, big"-0.25693933462703749003312586129e+02") - d706 = convert(T, big"-0.15418974869023643374053993627e+03") - d707 = convert(T, big"-0.23152937917604549567536039109e+03") - d708 = convert(T, big" 0.35763911791061412378285349910e+03") - d709 = convert(T, big" 0.93405324183624310003907691704e+02") - d710 = convert(T, big"-0.37458323136451633156875139351e+02") - d711 = convert(T, big" 0.10409964950896230045147246184e+03") - d712 = convert(T, big" 0.29840293426660503123344363579e+02") - d713 = convert(T, big"-0.43533456590011143754432175058e+02") - d714 = convert(T, big" 0.96324553959188282948394950600e+02") - d715 = convert(T, big"-0.39177261675615439165231486172e+02") - d716 = convert(T, big"-0.14972683625798562581422125276e+03") - - return d401, d406, d407, d408, d409, d410, d411, d412, d413, d414, d415, d416, d501, - d506, d507, d508, d509, d510, d511, d512, d513, d514, d515, d516, d601, d606, - d607, d608, d609, d610, d611, d612, d613, d614, d615, d616, d701, d706, d707, - d708, d709, d710, d711, d712, d713, d714, d715, d716 -end -struct PFRK87ConstantCache{T1, T2} <: OrdinaryDiffEqConstantCache - α0201::T1 - α0301::T1 - α0401::T1 - α0501::T1 - α0601::T1 - α0701::T1 - - α0302::T1 - - α0403::T1 - α0503::T1 - - α0504::T1 - α0604::T1 - α0704::T1 - - α0605::T1 - α0705::T1 - - α0706::T1 - - α0908::T1 - α1008::T1 - α1108::T1 - α1208::T1 - α1308::T1 - - α1009::T1 - α1109::T1 - α1209::T1 - α1309::T1 - - α1110::T1 - α1210::T1 - α1310::T1 - - α1211::T1 - α1311::T1 - - β1::T1 - β6::T1 - β7::T1 - β8::T1 - β9::T1 - β10::T1 - β11::T1 - β12::T1 - β13::T1 - - β1tilde::T1 - β6tilde::T1 - β7tilde::T1 - β8tilde::T1 - β9tilde::T1 - β10tilde::T1 - β11tilde::T1 - β12tilde::T1 - - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - c8::T2 - c9::T2 - c10::T2 - c11::T2 - c12::T2 - c13::T2 -end - -function PFRK87ConstantCache(T1::Type, T2::Type) - - # elements of Butcher Table - α0201 = convert(T1, 1 // 18) - α0301 = convert(T1, 1 // 48) - α0401 = convert(T1, 1 // 32) - α0501 = convert(T1, 5 // 16) - α0601 = convert(T1, 3 // 80) - α0701 = convert(T1, 29443841 // 614563906) - - α0302 = convert(T1, 1 // 16) - - α0403 = convert(T1, 3 // 32) - α0503 = convert(T1, -75 // 64) - - α0504 = convert(T1, 75 // 64) - α0604 = convert(T1, 3 // 16) - α0704 = convert(T1, 77736538 // 692538347) - - α0605 = convert(T1, 3 // 20) - α0705 = convert(T1, -28693883 // 1125000000) - - α0706 = convert(T1, 23124283 // 1800000000) - - α0908 = convert(T1, 800635310 // 3783071287) - α1008 = convert(T1, 393006217 // 1396673457) - α1108 = convert(T1, 15336726248 // 1032824649) - α1208 = convert(T1, 5232866602 // 850066563) - α1308 = convert(T1, -13158990841 // 6184727034) - - α1009 = convert(T1, 123872331 // 1001029789) - α1109 = convert(T1, -45442868181 // 3398467696) - α1209 = convert(T1, -4093664535 // 808688257) - α1309 = convert(T1, 3936647629 // 1978049680) - - α1110 = convert(T1, 3065993473 // 597172653) - α1210 = convert(T1, 3962137247 // 1805957418) - α1310 = convert(T1, -160528059 // 685178525) - - α1211 = convert(T1, 65686358 // 487910083) - α1311 = convert(T1, 248638103 // 1413531060) - - β1 = convert(T1, 14005451 // 335480064) - β6 = convert(T1, -59238493 // 1068277825) - β7 = convert(T1, 181606767 // 758867731) - β8 = convert(T1, 561292985 // 797845732) - β9 = convert(T1, -1041891430 // 1371343529) - β10 = convert(T1, 760417239 // 1151165299) - β11 = convert(T1, 118820643 // 751138087) - β12 = convert(T1, -528747749 // 2220607170) - β13 = convert(T1, 1 // 4) - - β1tilde = convert(T1, 13451932 // 455176623) - β6tilde = convert(T1, -808719846 // 976000145) - β7tilde = convert(T1, 1757004468 // 5645159321) - β8tilde = convert(T1, 656045339 // 265891186) - β9tilde = convert(T1, -3867574721 // 1518517206) - β10tilde = convert(T1, 465885868 // 322736535) - β11tilde = convert(T1, 53011238 // 667516719) - β12tilde = convert(T1, 2 // 45) - - c2 = convert(T2, 1 // 18) - c3 = convert(T2, 1 // 12) - c4 = convert(T2, 1 // 8) - c5 = convert(T2, 5 // 16) - c6 = convert(T2, 3 // 8) - c7 = convert(T2, 59 // 400) - c8 = convert(T2, 93 // 200) - c9 = convert(T2, 5490023248 // 9719169821) - c10 = convert(T2, 13 // 20) - c11 = convert(T2, 1201146811 // 1299019798) - c12 = convert(T2, 1 // 1) - c13 = convert(T2, 1 // 1) - - PFRK87ConstantCache(α0201, α0301, α0401, α0501, α0601, α0701, α0302, α0403, α0503, - α0504, α0604, α0704, α0605, α0705, α0706, α0908, α1008, α1108, - α1208, α1308, α1009, α1109, α1209, α1309, α1110, α1210, α1310, - α1211, α1311, β1, β6, β7, β8, β9, β10, β11, β12, β13, β1tilde, - β6tilde, β7tilde, β8tilde, β9tilde, β10tilde, β11tilde, β12tilde, - c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/interp_func.jl b/lib/OrdinaryDiffEqHighOrderRK/src/interp_func.jl deleted file mode 100644 index 6be33c0ada..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/interp_func.jl +++ /dev/null @@ -1,6 +0,0 @@ -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{DP8ConstantCache, DP8Cache}} - dense ? "specialized 7th order interpolation" : "1st order linear" -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqHighOrderRK/src/interpolants.jl b/lib/OrdinaryDiffEqHighOrderRK/src/interpolants.jl deleted file mode 100644 index 206dfa9293..0000000000 --- a/lib/OrdinaryDiffEqHighOrderRK/src/interpolants.jl +++ /dev/null @@ -1,138 +0,0 @@ -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) -Θ1 = 1 - Θ -# return @.. broadcast=false y₀ + dt*Θ*(k[1] + Θ1*(k[2] + Θ*(k[3]+Θ1*(k[4] + Θ*(k[5] + Θ1*(k[6]+Θ*k[7])))))) -return @inbounds y₀ + - dt * Θ * - (k[1] + - Θ1 * (k[2] + - Θ * (k[3] + Θ1 * (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) -Θ1 = 1 - Θ -# return @.. broadcast=false y₀[idxs] + dt*Θ*(k[1][idxs] + Θ1*(k[2][idxs] + Θ*(k[3][idxs]+Θ1*(k[4][idxs] + Θ*(k[5][idxs] + Θ1*(k[6][idxs]+Θ*k[7][idxs])))))) -return y₀[idxs] + - dt * Θ * - (k[1][idxs] + - Θ1 * (k[2][idxs] + - Θ * (k[3][idxs] + - Θ1 * (k[4][idxs] + Θ * (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - Θ1 = 1 - Θ - @inbounds @.. broadcast=false out=y₀ + - dt * Θ * - (k[1] + - Θ1 * (k[2] + - Θ * (k[3] + - Θ1 * - (k[4] + Θ * (k[5] + Θ1 * (k[6] + Θ * k[7])))))) - #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - Θ1 = 1 - Θ - @views @.. broadcast=false out=y₀[idxs] + - dt * Θ * - (k[1][idxs] + - Θ1 * (k[2][idxs] + - Θ * (k[3][idxs] + - Θ1 * (k[4][idxs] + - Θ * - (k[5][idxs] + Θ1 * (k[6][idxs] + Θ * k[7][idxs])))))) - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*Θ*(k[1][i] + Θ1*(k[2][i] + Θ*(k[3][i]+Θ1*(k[4][i] + Θ*(k[5][i] + Θ1*(k[6][i]+Θ*k[7][i])))))) - #end - out -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @inbounds b1diff = @.. broadcast=false k[1]+k[2] - @inbounds b2diff = @.. broadcast=false -2*k[2]+2*k[3]+2*k[4] - @inbounds b3diff = @.. broadcast=false -3 * k[3]-6 * k[4]+3*k[5]+3*k[6] - @inbounds b4diff = @.. broadcast=false 4 * k[4] - 8 * k[5] - 12 * k[6]+4 * k[7] - @inbounds b5diff = @.. broadcast=false 5 * k[5] + 15 * k[6]-15 * k[7] - @inbounds b6diff = @.. broadcast=false -6 * k[6]+18 * k[7] - @inbounds b7diff = @.. broadcast=false -7*k[7] - # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) - return b1diff + - Θ * - (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - b1diff = @.. broadcast=false k[1][idxs]+k[2][idxs] - b2diff = @.. broadcast=false -2*k[2][idxs]+2*k[3][idxs]+2*k[4][idxs] - b3diff = @.. broadcast=false -3 * k[3][idxs]-6 * k[4][idxs]+3*k[5][idxs]+3*k[6][idxs] - b4diff = @.. broadcast=false 4 * k[4][idxs] - 8 * k[5][idxs] - - 12 * k[6][idxs]+4 * k[7][idxs] - b5diff = @.. broadcast=false 5 * k[5][idxs] + 15 * k[6][idxs]-15 * k[7][idxs] - b6diff = @.. broadcast=false -6 * k[6][idxs]+18 * k[7][idxs] - b7diff = @.. broadcast=false -7*k[7][idxs] - # return @.. broadcast=false b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + Θ*(b5diff + Θ*(b6diff + Θ*b7diff))))) - return b1diff + - Θ * - (b2diff + Θ * (b3diff + Θ * (b4diff + Θ * (b5diff + Θ * (b6diff + Θ * b7diff))))) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - # b1diff = k[1] + k[2] - # b2diff = -2*k[2] + 2*k[3] + 2*k[4] - # b3diff = -3*k[3] - 6*k[4] + 3*k[5] + 3*k[6] - # b4diff = 4*k[4] - 8*k[5] - 12*k[6] + 4*k[7] - # b5diff = 5*k[5] + 15*k[6] - 15*k[7] - # b6diff = -6*k[6] + 18*k[7] - # @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + - # Θ*(b5diff + Θ*(b6diff - 7*k[7]*Θ))))) - @views @.. broadcast=false out=k[1] + k[2] + - Θ * (-2 * k[2] + 2 * k[3] + 2 * k[4] + - Θ * (-3 * k[3] - 6 * k[4] + 3 * k[5] + 3 * k[6] + - Θ * (4 * k[4] - 8 * k[5] - 12 * k[6] + 4 * k[7] + - Θ * (5 * k[5] + 15 * k[6] - 15 * k[7] + - Θ * (-6 * k[6] + 18 * k[7] - 7 * k[7] * Θ))))) - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP8ConstantCache, DP8Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - # b1diff = k[1][idxs] + k[2][idxs] - # b2diff = -2*k[2][idxs] + 2*k[3][idxs] + 2*k[4][idxs] - # b3diff = -3*k[3][idxs] - 6*k[4][idxs] + 3*k[5][idxs] + 3*k[6][idxs] - # b4diff = 4*k[4][idxs] - 8*k[5][idxs] - 12*k[6][idxs] + 4*k[7][idxs] - # b5diff = 5*k[5][idxs] + 15*k[6][idxs] - 15*k[7][idxs] - # b6diff = -6*k[6][idxs] + 18*k[7][idxs] - #@views @.. broadcast=false out = b1diff + Θ*(b2diff + Θ*(b3diff + Θ*(b4diff + - # Θ*(b5diff + Θ*(b6diff - 7*k[7][idxs]*Θ))))) - @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] + - Θ * (-2 * k[2][idxs] + 2 * k[3][idxs] + 2 * k[4][idxs] + - Θ * - (-3 * k[3][idxs] - 6 * k[4][idxs] + 3 * k[5][idxs] + - 3 * k[6][idxs] + - Θ * - (4 * k[4][idxs] - 8 * k[5][idxs] - 12 * k[6][idxs] + - 4 * k[7][idxs] + - Θ * - (5 * k[5][idxs] + 15 * k[6][idxs] - 15 * k[7][idxs] + - Θ * (-6 * k[6][idxs] + 18 * k[7][idxs] - - 7 * k[7][idxs] * Θ))))) - out -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/Project.toml b/lib/OrdinaryDiffEqLowOrderRK/Project.toml deleted file mode 100644 index 42d0e25784..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/Project.toml +++ /dev/null @@ -1,22 +0,0 @@ -name = "OrdinaryDiffEqLowOrderRK" -uuid = "0e0916b3-e0a4-463e-8dfa-d409d9d724ed" -authors = ["ParamThakkar123 "] -version = "0.1.0" - -[deps] -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" - -[compat] -julia = "1.10" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl b/lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl deleted file mode 100644 index 806dfe4dd6..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/OrdinaryDiffEqLowOrderRK.jl +++ /dev/null @@ -1,33 +0,0 @@ -module OrdinaryLowOrderRK - -import OrdinaryDiffEq: alg_order, calculate_residuals!, - initialize!, perform_step!, @unpack, unwrap_alg, - calculate_residuals, - OrdinaryDiffEqAlgorithm, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqAdaptiveAlgorithm, OrdinaryDiffEqPartitionedAlgorithm, - CompiledFloats, uses_uprev, - alg_cache, _vec, _reshape, @cache, isfsal, full_cache, - constvalue, _unwrap_val, du_alias_or_new, - explicit_rk_docstring, trivial_limiter!, - _ode_interpolant!, _ode_addsteps! -using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools - -include("algorithms.jl") -include("alg_utils.jl") -include("low_order_rk_caches.jl") -include("interp_func.jl") -include("interpolants.jl") -include("fixed_timestep_perform_step.jl") -include("low_order_rk_addsteps.jl") -include("low_order_rk_tableaus.jl") -include("low_order_rk_caches.jl") -include("split_perform_step.jl") - -export FunctionMap, Heun, Ralston, Midpoint, OwrenZen3, OwrenZen4, - OwrenZen5, RK4, BS3, BS5, Tsit5, DP5, Anas5, RKO65, - FRK65, RKM, MSRK5, MSRK6, PSRK4p7q6, PSRK3p6q5, - Stepanov5, SIR54, Alshina2, Alshina3, Alshina6, Euler, - PSRK3p5q4, SplitEuler - -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/alg_utils.jl b/lib/OrdinaryDiffEqLowOrderRK/src/alg_utils.jl deleted file mode 100644 index 6cfdd74af8..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/alg_utils.jl +++ /dev/null @@ -1,47 +0,0 @@ -alg_order(alg::Heun) = 2 -alg_order(alg::Euler) = 1 -alg_order(alg::Ralston) = 2 -alg_order(alg::SplitEuler) = 1 -alg_order(alg::Midpoint) = 2 -alg_order(alg::RK4) = 4 -alg_order(alg::BS3) = 3 -alg_order(alg::OwrenZen3) = 3 -alg_order(alg::OwrenZen4) = 4 -alg_order(alg::OwrenZen5) = 5 -alg_order(alg::BS5) = 5 -alg_order(alg::Tsit5) = 5 -alg_order(alg::DP5) = 5 -alg_order(alg::Anas5) = 5 -alg_order(alg::RKO65) = 5 -alg_order(alg::FRK65) = 6 -alg_order(alg::RKM) = 4 -alg_order(alg::MSRK6) = 6 -alg_order(alg::MSRK5) = 5 -alg_order(alg::PSRK4p7q6) = 4 -alg_order(alg::PSRK3p6q5) = 3 -alg_order(alg::Stepanov5) = 5 -alg_order(alg::SIR54) = 5 -alg_order(alg::Alshina2) = 2 -alg_order(alg::Alshina3) = 3 -alg_order(alg::Alshina6) = 6 -alg_order(alg::PSRK3p5q4) = 3 -alg_order(alg::FunctionMap) = 0 - -isfsal(alg::FunctionMap) = false -isfsal(alg::RKO65) = false -isfsal(alg::FRK65) = true -isfsal(alg::PSRK3p5q4) = false -isfsal(alg::RKM) = false -isfsal(alg::PSRK4p7q6) = false -isfsal(alg::PSRK3p6q5) = false - -beta2_default(alg::DP5) = 4 // 100 -beta2_default(alg::FunctionMap) = 0 - -beta1_default(alg::DP5, beta2) = typeof(beta2)(1 // alg_order(alg)) - 3beta2 / 4 -beta1_default(alg::FunctionMap, beta2) = 0 - -alg_stability_size(alg::Tsit5) = 3.5068 -alg_stability_size(alg::DP5) = 3.3066 - -ssp_coefficient(alg::Euler) = 1 \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/algorithms.jl b/lib/OrdinaryDiffEqLowOrderRK/src/algorithms.jl deleted file mode 100644 index f71127bd91..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/algorithms.jl +++ /dev/null @@ -1,632 +0,0 @@ -@doc explicit_rk_docstring( - "The second order Heun's method. Uses embedded Euler method for adaptivity.", - "Heun") -Base.@kwdef struct Heun{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Heun(stage_limiter!, step_limiter! = trivial_limiter!) - Heun(stage_limiter!, step_limiter!, False()) -end - -struct SplitEuler <: - OrdinaryDiffEqExponentialAlgorithm{0, false, Val{:forward}, Val{true}, nothing} end - -struct Euler <: OrdinaryDiffEqAlgorithm end - -@doc explicit_rk_docstring( - "The optimized second order midpoint method. Uses embedded Euler method for adaptivity.", - "Ralston") -Base.@kwdef struct Ralston{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Ralston(stage_limiter!, step_limiter! = trivial_limiter!) - Ralston(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "The second order midpoint method. Uses embedded Euler method for adaptivity.", - "Midpoint") -Base.@kwdef struct Midpoint{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Midpoint(stage_limiter!, step_limiter! = trivial_limiter!) - Midpoint(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("The canonical Runge-Kutta Order 4 method. -Uses a defect control for adaptive stepping using maximum error over the whole interval.", - "RK4", - references = "@article{shampine2005solving, - title={Solving ODEs and DDEs with residual control}, - author={Shampine, LF}, - journal={Applied Numerical Mathematics}, - volume={52}, - number={1}, - pages={113--127}, - year={2005}, - publisher={Elsevier} - }") -Base.@kwdef struct RK4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function RK4(stage_limiter!, step_limiter! = trivial_limiter!) - RK4(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "A third-order, four-stage explicit FSAL Runge-Kutta method with embedded error -estimator of Bogacki and Shampine.", - "BS3", - references = "@article{bogacki19893, - title={A 3 (2) pair of Runge-Kutta formulas}, - author={Bogacki, Przemyslaw and Shampine, Lawrence F}, - journal={Applied Mathematics Letters}, - volume={2}, - number={4}, - pages={321--325}, - year={1989}, - publisher={Elsevier} - }") -Base.@kwdef struct BS3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function BS3(stage_limiter!, step_limiter! = trivial_limiter!) - BS3(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Owren-Zennaro optimized interpolation 3/2 method (free 3rd order interpolant).", - "OwrenZen3", - references = "@article{owren1992derivation, - title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, - author={Owren, Brynjulf and Zennaro, Marino}, - journal={SIAM journal on scientific and statistical computing}, - volume={13}, - number={6}, - pages={1488--1501}, - year={1992}, - publisher={SIAM} - }") -Base.@kwdef struct OwrenZen3{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function OwrenZen3(stage_limiter!, step_limiter! = trivial_limiter!) - OwrenZen3(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Owren-Zennaro optimized interpolation 4/3 method (free 4th order interpolant).", - "OwrenZen4", - references = "@article{owren1992derivation, - title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, - author={Owren, Brynjulf and Zennaro, Marino}, - journal={SIAM journal on scientific and statistical computing}, - volume={13}, - number={6}, - pages={1488--1501}, - year={1992}, - publisher={SIAM} - }") -Base.@kwdef struct OwrenZen4{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function OwrenZen4(stage_limiter!, step_limiter! = trivial_limiter!) - OwrenZen4(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Owren-Zennaro optimized interpolation 5/4 method (free 5th order interpolant).", - "OwrenZen5", - references = "@article{owren1992derivation, - title={Derivation of efficient, continuous, explicit Runge--Kutta methods}, - author={Owren, Brynjulf and Zennaro, Marino}, - journal={SIAM journal on scientific and statistical computing}, - volume={13}, - number={6}, - pages={1488--1501}, - year={1992}, - publisher={SIAM} - }") -Base.@kwdef struct OwrenZen5{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function OwrenZen5(stage_limiter!, step_limiter! = trivial_limiter!) - OwrenZen5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Bogacki-Shampine 5/4 Runge-Kutta method. (lazy 5th order interpolant).", - "BS5", - references = "@article{bogacki1996efficient, - title={An efficient runge-kutta (4, 5) pair}, - author={Bogacki, P and Shampine, Lawrence F}, - journal={Computers \\& Mathematics with Applications}, - volume={32}, - number={6}, - pages={15--28}, - year={1996}, - publisher={Elsevier} - }", - extra_keyword_description = """- `lazy`: determines if the lazy interpolant is used. - """, - extra_keyword_default = "lazy = true") -Base.@kwdef struct BS5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - lazy::Bool = true -end -# for backwards compatibility -function BS5(stage_limiter!, step_limiter! = trivial_limiter!; lazy = true) - BS5(stage_limiter!, step_limiter!, False(), lazy) -end - -@doc explicit_rk_docstring( - "A fifth-order explicit Runge-Kutta method with embedded error -estimator of Tsitouras. Free 4th order interpolant.", "Tsit5", - references = "@article{tsitouras2011runge, - title={Runge--Kutta pairs of order 5 (4) satisfying only the first column simplifying assumption}, - author={Tsitouras, Ch}, - journal={Computers \\& Mathematics with Applications}, - volume={62}, - number={2}, - pages={770--775}, - year={2011}, - publisher={Elsevier} - }") -Base.@kwdef struct Tsit5{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -TruncatedStacktraces.@truncate_stacktrace Tsit5 3 -# for backwards compatibility -function Tsit5(stage_limiter!, step_limiter! = trivial_limiter!) - Tsit5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring( - "Dormand-Prince's 5/4 Runge-Kutta method. (free 4th order interpolant).", - "DP5", - references = "@article{dormand1980family, - title={A family of embedded Runge-Kutta formulae}, - author={Dormand, John R and Prince, Peter J}, - journal={Journal of computational and applied mathematics}, - volume={6}, - number={1}, - pages={19--26}, - year={1980}, - publisher={Elsevier} - }") -Base.@kwdef struct DP5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function DP5(stage_limiter!, step_limiter! = trivial_limiter!) - DP5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("4th order Runge-Kutta method designed for periodic problems.", - "Anas5", - extra_keyword_description = """- `w`: a periodicity estimate, which when accurate the method becomes 5th order - (and is otherwise 4th order with less error for better estimates). - """, - extra_keyword_default = "w = 1") -Base.@kwdef struct Anas5{StageLimiter, StepLimiter, Thread, T} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - w::T = 1 -end -# for backwards compatibility -function Anas5(stage_limiter!, step_limiter! = trivial_limiter!; w = 1) - Anas5(stage_limiter!, step_limiter!, False(), w) -end - -@doc explicit_rk_docstring("5th order Explicit RK method.", "RKO5", - references = "Tsitouras, Ch. \"Explicit Runge–Kutta methods for starting integration of - Lane–Emden problem.\" Applied Mathematics and Computation 354 (2019): 353-364. - doi: https://doi.org/10.1016/j.amc.2019.02.047") -Base.@kwdef struct RKO65{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function RKO65(stage_limiter!, step_limiter! = trivial_limiter!) - RKO65(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("Zero Dissipation Runge-Kutta of 6th order.", "FRK65", - extra_keyword_description = """- `omega`: a periodicity phase estimate, - when accurate this method results in zero numerical dissipation. - """, - extra_keyword_default = "omega = 0.0") -Base.@kwdef struct FRK65{StageLimiter, StepLimiter, Thread, T} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() - omega::T = 0.0 -end - -# for backwards compatibility -function FRK65(stage_limiter!, step_limiter! = trivial_limiter!; omega = 0.0) - FRK65(stage_limiter!, step_limiter!, False(), omega) -end - -@doc explicit_rk_docstring("TBD", "RKM") -Base.@kwdef struct RKM{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function RKM(stage_limiter!, step_limiter! = trivial_limiter!) - RKM(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("5th order Explicit RK method.", "MSRK5", - references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Figure 3.") -Base.@kwdef struct MSRK5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function MSRK5(stage_limiter!, step_limiter! = trivial_limiter!) - MSRK5(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("6th order Explicit RK method.", "MSRK6", - references = "Misha Stepanov - https://arxiv.org/pdf/2202.08443.pdf : Table4") -Base.@kwdef struct MSRK6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function MSRK6(stage_limiter!, step_limiter! = trivial_limiter!) - MSRK6(stage_limiter!, step_limiter!, False()) -end - -@doc explicit_rk_docstring("6-stage Pseudo-Symplectic Explicit RK method.", "4p7q(6)", - references = "@article{Aubry1998, - author = {A. Aubry and P. Chartier}, - journal = {BIT Numer. Math.}, - title = {Pseudo-symplectic {R}unge-{K}utta methods}, - volume = {38}, - PAGES = {439-461}, - year = {1998}, - }, - @article{Capuano2017, - title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, - journal = {J. Comput. Phys.}, - volume = {328}, - pages = {86-94}, - year = {2017}, - issn = {0021-9991}, - doi = {https://doi.org/10.1016/j.jcp.2016.10.040}, - author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") -Base.@kwdef struct PSRK4p7q6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end - -@doc explicit_rk_docstring("5-stage Pseudo-Symplectic Explicit RK method.", "3p6q(5)", - references = "@article{Aubry1998, - author = {A. Aubry and P. Chartier}, - journal = {BIT Numer. Math.}, - title = {Pseudo-symplectic {R}unge-{K}utta methods}, - year = {1998}, - }, - @article{Capuano2017, - title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, - journal = {J. Comput. Phys.}, - year = {2017}, - author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") -Base.@kwdef struct PSRK3p6q5{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end - -@doc explicit_rk_docstring("5th order Explicit RK method.", - "Stepanov5", - references = "@article{Stepanov2021Embedded5, - title={Embedded (4, 5) pairs of explicit 7-stage Runge–Kutta methods with FSAL property}, - author={Misha Stepanov}, - journal={Calcolo}, - year={2021}, - volume={59} - }") -Base.@kwdef struct Stepanov5{StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end -# for backwards compatibility -function Stepanov5(stage_limiter!, step_limiter! = trivial_limiter!) - Stepanov5(stage_limiter!, step_limiter!, False()) -end - -@inline trivial_limiter!(u, integrator, p, t) = nothing -""" - SIR54(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -5th order Explicit RK method suited for SIR-type epidemic models. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Kovalnogov2020RungeKuttaPS, -title={Runge–Kutta pairs suited for SIR‐type epidemic models}, -author={Vladislav N. Kovalnogov and Theodore E. Simos and Ch. Tsitouras}, -journal={Mathematical Methods in the Applied Sciences}, -year={2020}, -volume={44}, -pages={5210 - 5216} -} -""" -struct SIR54{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function SIR54(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - SIR54{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -# for backwards compatibility -function SIR54(stage_limiter!, step_limiter! = trivial_limiter!) - SIR54{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::SIR54) - print(io, "SIR54(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - -""" - Alshina2(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -2nd order, 2-stage Explicit Runge-Kutta Method with optimal parameters. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Alshina2008, -doi = {10.1134/s0965542508030068}, -url = {https://doi.org/10.1134/s0965542508030068}, -year = {2008}, -month = mar, -publisher = {Pleiades Publishing Ltd}, -volume = {48}, -number = {3}, -pages = {395--405}, -author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, -title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, -journal = {Computational Mathematics and Mathematical Physics} -} -""" -struct Alshina2{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function Alshina2(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - Alshina2{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -function Alshina2(stage_limiter!, step_limiter! = trivial_limiter!) - Alshina2{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::Alshina2) - print(io, "Alshina2(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - -""" - Alshina3(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -3rd order, 3-stage Explicit Runge-Kutta Method with optimal parameters. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Alshina2008, -doi = {10.1134/s0965542508030068}, -url = {https://doi.org/10.1134/s0965542508030068}, -year = {2008}, -month = mar, -publisher = {Pleiades Publishing Ltd}, -volume = {48}, -number = {3}, -pages = {395--405}, -author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, -title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, -journal = {Computational Mathematics and Mathematical Physics} -} -""" -struct Alshina3{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAdaptiveAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function Alshina3(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - Alshina3{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -function Alshina3(stage_limiter!, step_limiter! = trivial_limiter!) - Alshina3{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::Alshina3) - print(io, "Alshina3(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - -""" - Alshina6(; stage_limiter! = OrdinaryDiffEq.trivial_limiter!, - step_limiter! = OrdinaryDiffEq.trivial_limiter!, - thread = OrdinaryDiffEq.False()) - -6th order, 7-stage Explicit Runge-Kutta Method with optimal parameters. - -Like SSPRK methods, this method also takes optional arguments `stage_limiter!` -and `step_limiter!`, where `stage_limiter!` and `step_limiter!` are functions -of the form `limiter!(u, integrator, p, t)`. - -The argument `thread` determines whether internal broadcasting on -appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`, -default) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when -Julia is started with multiple threads. - -## Reference - -@article{Alshina2008, -doi = {10.1134/s0965542508030068}, -url = {https://doi.org/10.1134/s0965542508030068}, -year = {2008}, -month = mar, -publisher = {Pleiades Publishing Ltd}, -volume = {48}, -number = {3}, -pages = {395--405}, -author = {E. A. Alshina and E. M. Zaks and N. N. Kalitkin}, -title = {Optimal first- to sixth-order accurate Runge-Kutta schemes}, -journal = {Computational Mathematics and Mathematical Physics} -} -""" -struct Alshina6{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function Alshina6(; stage_limiter! = trivial_limiter!, step_limiter! = trivial_limiter!, - thread = False()) - Alshina6{typeof(stage_limiter!), typeof(step_limiter!), typeof(thread)}(stage_limiter!, - step_limiter!, - thread) -end - -function Alshina6(stage_limiter!, step_limiter! = trivial_limiter!) - Alshina6{typeof(stage_limiter!), typeof(step_limiter!), False}(stage_limiter!, - step_limiter!, - False()) -end - -function Base.show(io::IO, alg::Alshina6) - print(io, "Alshina6(stage_limiter! = ", alg.stage_limiter!, - ", step_limiter! = ", alg.step_limiter!, - ", thread = ", alg.thread, ")") -end - -@doc explicit_rk_docstring("4-stage Pseudo-Symplectic Explicit RK method.", "3p5q(4)", - references = "@article{Aubry1998, - author = {A. Aubry and P. Chartier}, - journal = {BIT Numer. Math.}, - title = {Pseudo-symplectic {R}unge-{K}utta methods}, - year = {1998}, - }, - @article{Capuano2017, - title = {Explicit {R}unge–{K}utta schemes for incompressible flow with improved energy-conservation properties}, - journal = {J. Comput. Phys.}, - year = {2017}, - author = {F. Capuano and G. Coppola and L. Rández and L. {de Luca}},}") -Base.@kwdef struct PSRK3p5q4{StageLimiter, StepLimiter, Thread} <: OrdinaryDiffEqAlgorithm - stage_limiter!::StageLimiter = trivial_limiter! - step_limiter!::StepLimiter = trivial_limiter! - thread::Thread = False() -end - -struct FunctionMap{scale_by_time} <: OrdinaryDiffEqAlgorithm end -FunctionMap(; scale_by_time = false) = FunctionMap{scale_by_time}() \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/fixed_timestep_perform_step.jl b/lib/OrdinaryDiffEqLowOrderRK/src/fixed_timestep_perform_step.jl deleted file mode 100644 index 46b9746215..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/fixed_timestep_perform_step.jl +++ /dev/null @@ -1,487 +0,0 @@ -function initialize!(integrator, cache::Union{HeunConstantCache, RalstonConstantCache}) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, - cache::Union{HeunConstantCache, RalstonConstantCache}, - repeat_step = false) - @unpack t, dt, uprev, u, f, p, fsalfirst = integrator - - # precalculations - if cache isa HeunConstantCache - a₁ = dt - a₂ = dt / 2 - else # Ralston - a₁ = 2 * dt / 3 - a₂ = dt / 4 - a₃ = 3 * a₂ - end - - tmp = @.. broadcast=false uprev+a₁ * fsalfirst - k2 = f(tmp, p, t + a₁) - integrator.stats.nf += 1 - - if cache isa HeunConstantCache - u = @.. broadcast=false uprev+a₂ * (fsalfirst + k2) - else - u = @.. broadcast=false uprev+a₂*fsalfirst+a₃*k2 - end - - if integrator.opts.adaptive - if cache isa HeunConstantCache - tmp = @.. broadcast=false a₂*(k2 - fsalfirst) - else - tmp = @.. broadcast=false a₃*(k2 - fsalfirst) - end - - atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - k = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.fsallast = k - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::Union{HeunCache, RalstonCache}) - integrator.kshortsize = 2 - @unpack k, fsalfirst = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::Union{HeunCache, RalstonCache}, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack fsalfirst, k, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - - # precalculations - if cache isa HeunCache - a₁ = dt - a₂ = dt / 2 - else # Ralston - a₁ = 2 * dt / 3 - a₂ = dt / 4 - a₃ = 3 * a₂ - end - - @.. broadcast=false thread=thread tmp=uprev + a₁ * fsalfirst - stage_limiter!(tmp, integrator, p, t + a₁) - f(k, tmp, p, t + a₁) - integrator.stats.nf += 1 - - if cache isa HeunCache - @.. broadcast=false thread=thread u=uprev + a₂ * (fsalfirst + k) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - else - @.. broadcast=false thread=thread u=uprev + a₂ * fsalfirst + a₃ * k - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - end - - if integrator.opts.adaptive - if cache isa HeunCache - @.. broadcast=false thread=thread tmp=a₂ * (k - fsalfirst) - else - @.. broadcast=false thread=thread tmp=a₃ * (k - fsalfirst) - end - - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function initialize!(integrator, cache::MidpointCache) - @unpack k, fsalfirst = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # FSAL for interpolation - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::MidpointCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, k, fsalfirst, atmp, stage_limiter!, step_limiter!, thread = cache - halfdt = dt / 2 - @.. broadcast=false thread=thread tmp=uprev + halfdt * fsalfirst - stage_limiter!(k, tmp, p, t + halfdt) - f(k, tmp, p, t + halfdt) - integrator.stats.nf += 1 - @.. broadcast=false thread=thread u=uprev + dt * k - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - if integrator.opts.adaptive - @.. broadcast=false thread=thread tmp=dt * (fsalfirst - k) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - f(k, u, p, t + dt) - integrator.stats.nf += 1 -end - -function initialize!(integrator, cache::Anas5ConstantCache) - integrator.kshortsize = 7 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::Anas5ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache - ## Note that c1 and b2 were 0. - alg = unwrap_alg(integrator, false) - w = alg.w - v = w * dt - ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. - a65 = (-8000 // 1071) * - (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + - 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) - a61 += (-119 // 200) * a65 - a63 += (189 // 100) * a65 - a64 += (-459 // 200) * a65 - k1 = integrator.fsalfirst - k2 = f(uprev + dt * a21 * k1, p, t + c2 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c3 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + 2 * k3), p, t + c4 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c5 * dt) - k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, - t + c6 * dt) - u = uprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) - k7 = f(u, p, t + dt) - integrator.fsallast = k7 - integrator.stats.nf += 6 - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.u = u -end - -function initialize!(integrator, cache::Anas5Cache) - integrator.kshortsize = 7 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k7 # setup pointers - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::Anas5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - uidx = eachindex(integrator.uprev) - @unpack k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6 = cache.tab - alg = unwrap_alg(integrator, false) - w = alg.w - v = w * dt - ## Formula by Z.A. Anastassi, see the Anas5 caches in tableaus/low_order_rk_tableaus.jl for the full citation. - a65 = (-8000 // 1071) * - (-a43 * (v^5) + 6 * tan(v) * (v^4) + 24 * (v^3) - 72 * tan(v) * (v^2) - 144 * v + - 144 * tan(v)) / ((v^5) * (a43 * tan(v) * v + 12 - 10 * a43)) - a61 += (-119 // 200) * a65 - a63 += (189 // 100) * a65 - a64 += (-459 // 200) * a65 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + a21 * k1[i] - end - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + dt * (a31 * k1[i] + a32 * k2[i]) - end - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + dt * (a41 * k1[i] + a42 * k2[i] + 2 * k3[i]) - end - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + - dt * (a51 * k1[i] + a52 * k2[i] + a53 * k3[i] + a54 * k4[i]) - end - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i] + - dt * (a61 * k1[i] + a62 * k2[i] + a63 * k3[i] + a64 * k4[i] + - a65 * k5[i]) - end - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @tight_loop_macros for i in uidx - @inbounds u[i] = uprev[i] + - dt * - (b1 * k1[i] + b3 * k3[i] + b4 * k4[i] + b5 * k5[i] + b6 * k6[i]) - end - stage_limiter!(tmp, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k7, u, p, t + dt) - integrator.stats.nf += 6 -end - -function initialize!(integrator, cache::RK4ConstantCache) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::RK4ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - halfdt = dt / 2 - k₁ = integrator.fsalfirst - ttmp = t + halfdt - k₂ = f(uprev + halfdt * k₁, p, ttmp) - k₃ = f(uprev + halfdt * k₂, p, ttmp) - k₄ = f(uprev + dt * k₃, p, t + dt) - u = uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 4 - if integrator.opts.adaptive - # Shampine Solving ODEs and DDEs with Residual Control Estimate - k₅ = integrator.fsallast - - # one(t) so that types are correct but unitless - σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 - σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 - p1 = (1 - σ₁) * uprev + σ₁ * u + - σ₁ * (σ₁ - 1) * ((1 - 2σ₁) * (u - uprev) + (σ₁ - 1) * dt * k₁ + σ₁ * dt * k₅) - p2 = (1 - σ₂) * uprev + σ₂ * u + - σ₂ * (σ₂ - 1) * ((1 - 2σ₂) * (u - uprev) + (σ₂ - 1) * dt * k₁ + σ₂ * dt * k₅) - pprime1 = k₁ + - σ₁ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₁ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt - pprime2 = k₁ + - σ₂ * (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₂ * (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - 6 * u) + 6 * u) / dt - e1 = integrator.opts.internalnorm( - calculate_residuals(dt * (f(p1, p, t + σ₁ * dt) - - pprime1), uprev, u, - integrator.opts.abstol, - integrator.opts.reltol, - integrator.opts.internalnorm, - t), - t) - e2 = integrator.opts.internalnorm( - calculate_residuals(dt * (f(p2, p, t + σ₂ * dt) - - pprime2), uprev, u, - integrator.opts.abstol, - integrator.opts.reltol, - integrator.opts.internalnorm, - t), - t) - integrator.stats.nf += 2 - integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) - end - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::RK4Cache) - @unpack tmp, fsalfirst, k₂, k₃, k₄, k = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # pre-start FSAL - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::RK4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k₂, k₃, k₄, k, atmp, stage_limiter!, step_limiter!, thread = cache - k₁ = fsalfirst - halfdt = dt / 2 - ttmp = t + halfdt - @.. broadcast=false thread=thread tmp=uprev + halfdt * k₁ - stage_limiter!(tmp, integrator, p, ttmp) - f(k₂, tmp, p, ttmp) - @.. broadcast=false thread=thread tmp=uprev + halfdt * k₂ - stage_limiter!(tmp, integrator, p, ttmp) - f(k₃, tmp, p, ttmp) - @.. broadcast=false thread=thread tmp=uprev + dt * k₃ - stage_limiter!(tmp, integrator, p, t + dt) - f(k₄, tmp, p, t + dt) - @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (k₂ + k₃) + (k₁ + k₄)) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k, u, p, t + dt) - integrator.stats.nf += 4 - if integrator.opts.adaptive - # Shampine Solving ODEs and DDEs with Residual Control Estimate - k₅ = k - _p = k₂ - pprime = k₃ # Alias some cache arrays - # one(t) so that types are correct but unitless - σ₁ = one(t) * (1 // 2) - sqrt(one(t) * 3) / 6 - σ₂ = one(t) * (1 // 2) + sqrt(one(t) * 3) / 6 - @.. broadcast=false thread=thread tmp=(1 - σ₁) * uprev + σ₁ * u + - σ₁ * (σ₁ - 1) * - ((1 - 2σ₁) * (u - uprev) + - (σ₁ - 1) * dt * k₁ + - σ₁ * dt * k₅) - @.. broadcast=false thread=thread pprime=k₁ + - σ₁ * - (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₁ * - (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - - 6 * u) + - 6 * u) / dt - f(_p, tmp, p, t + σ₁ * dt) - @.. broadcast=false thread=thread tmp=dt * (_p - pprime) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - e1 = integrator.opts.internalnorm(atmp, t) - @.. broadcast=false thread=thread tmp=(1 - σ₂) * uprev + σ₂ * u + - σ₂ * (σ₂ - 1) * - ((1 - 2σ₂) * (u - uprev) + - (σ₂ - 1) * dt * k₁ + - σ₂ * dt * k₅) - @.. broadcast=false thread=thread pprime=k₁ + - σ₂ * - (-4 * dt * k₁ - 2 * dt * k₅ - 6 * uprev + - σ₂ * - (3 * dt * k₁ + 3 * dt * k₅ + 6 * uprev - - 6 * u) + - 6 * u) / dt - f(_p, tmp, p, t + σ₂ * dt) - @.. broadcast=false thread=thread tmp=dt * (_p - pprime) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - e2 = integrator.opts.internalnorm(atmp, t) - integrator.EEst = convert(typeof(one(t)), 2.1342) * max(e1, e2) - integrator.stats.nf += 2 - end -end - -function initialize!(integrator, cache::MidpointConstantCache) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::MidpointConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - halfdt = dt / 2 - tmp = @.. broadcast=false uprev+halfdt * integrator.fsalfirst - k = f(tmp, p, t + halfdt) - integrator.stats.nf += 1 - u = @.. broadcast=false uprev+dt * k - integrator.fsallast = f(u, p, t + dt) # For interpolation, then FSAL'd - integrator.stats.nf += 1 - if integrator.opts.adaptive - utilde = @.. broadcast=false dt*(integrator.fsalfirst - k) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::EulerConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::EulerConstantCache, repeat_step = false) - @unpack t, dt, uprev, f, p = integrator - @muladd u = @.. broadcast=false uprev+dt * integrator.fsalfirst - k = f(u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 - integrator.fsallast = k - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::EulerCache) - integrator.kshortsize = 2 - @unpack k, fsalfirst = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::EulerCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @muladd @.. broadcast=false u=uprev + dt * integrator.fsalfirst - f(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/interp_func.jl b/lib/OrdinaryDiffEqLowOrderRK/src/interp_func.jl deleted file mode 100644 index 1ac8d6c154..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/interp_func.jl +++ /dev/null @@ -1,52 +0,0 @@ -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: Union{OwrenZen3Cache, - OwrenZen3ConstantCache}} - dense ? "specialized 3rd order \"free\" interpolation" : "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: Union{OwrenZen4Cache, - OwrenZen4ConstantCache}} - dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: Union{OwrenZen5Cache, - OwrenZen5ConstantCache}} - dense ? "specialized 5th order \"free\" interpolation" : "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{BS5ConstantCache, BS5Cache}} - dense ? "specialized 5th order lazy interpolation" : "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Tsit5Cache, Tsit5ConstantCache -}} - dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{DP5ConstantCache, DP5Cache}} - dense ? "specialized 4th order \"free\" interpolation" : "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where {cacheType <: - FunctionMapConstantCache} - "left-endpoint piecewise constant" -end -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where {cacheType <: FunctionMapCache} - "left-endpoint piecewise constant" -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/interpolants.jl b/lib/OrdinaryDiffEqLowOrderRK/src/interpolants.jl deleted file mode 100644 index ead344d493..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/interpolants.jl +++ /dev/null @@ -1,1536 +0,0 @@ -RK_WITH_SPECIAL_INTERPOLATIONS = Union{ - OwrenZen3ConstantCache, OwrenZen3Cache, - OwrenZen4ConstantCache, OwrenZen4Cache, - OwrenZen5ConstantCache, OwrenZen5Cache, - DP5ConstantCache, DP5Cache, - Tsit5ConstantCache, Tsit5Cache, - BS5ConstantCache, BS5Cache, - FunctionMapConstantCache, FunctionMapCache -} - -function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::RK_WITH_SPECIAL_INTERPOLATIONS, - idxs, T::Type{Val{D}}, differential_vars) where {D} - throw(DerivativeOrderNotPossibleError()) -end - -function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::RK_WITH_SPECIAL_INTERPOLATIONS, - idxs, T::Type{Val{D}}, differential_vars) where {D} - throw(DerivativeOrderNotPossibleError()) -end - -function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::RK_WITH_SPECIAL_INTERPOLATIONS, - idxs, T::Type{Val{D}}, differential_vars) where {D} -throw(DerivativeOrderNotPossibleError()) -end - -function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::RK_WITH_SPECIAL_INTERPOLATIONS, - idxs, T::Type{Val{D}}, differential_vars) where {D} -throw(DerivativeOrderNotPossibleError()) -end - -#### - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) -y₀ -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) -y₀[idxs] -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) -recursivecopy!(out, y₀) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{FunctionMapConstantCache, FunctionMapCache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) -@views out[idxs] .= y₀[idxs] -end - -@def owrenzen3unpack begin - if cache isa OrdinaryDiffEqMutableCache - @unpack r13, r12, r23, r22, r33, r32 = cache.tab - else - @unpack r13, r12, r23, r22, r33, r32 = cache - end -end - -@def owrenzen3pre0 begin - @owrenzen3unpack - Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, 1, r12, r13) - b2Θ = Θ² * @evalpoly(Θ, r22, r23) - b3Θ = Θ² * @evalpoly(Θ, r32, r33) - b4Θ = Θ² * @evalpoly(Θ, -1, 1) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 - @inbounds @.. broadcast=false y₀+dt * - (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 - @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + - k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 - @inbounds @.. broadcast=false out=y₀ + - dt * - (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ) - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen3pre0 - @views @.. broadcast=false out=y₀[idxs] + - dt * - (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ) - out -end - -@def owrenzen3pre1 begin - @owrenzen3unpack - b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13) - b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23) - b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33) - b4Θdiff = Θ * @evalpoly(Θ, -2, 3) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen3pre1 - @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen3pre1 - @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[2][idxs]*b2Θdiff+k[3][idxs]*b3Θdiff+ - k[4][idxs]*b4Θdiff -end - -@def owrenzen3pre2 begin - @owrenzen3unpack - b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13) - b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23) - b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33) - b4Θdiff2 = @evalpoly(Θ, -2, 6) - invdt = inv(dt) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @inbounds @.. broadcast=false (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2)*invdt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + - k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2)*invdt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2) * invdt - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen3pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + - k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2) * invdt - out -end - -@def owrenzen3pre3 begin - @owrenzen3unpack - b1Θdiff3 = 6 * r13 - b2Θdiff3 = 6 * r23 - b3Θdiff3 = 6 * r33 - b4Θdiff3 = 6 - invdt2 = inv(dt)^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3)*invdt2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + - k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3)*invdt2 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3) * invdt2 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen3ConstantCache, OwrenZen3Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen3pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + - k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3) * invdt2 - out -end - -""" -""" - -@def owrenzen4unpack begin - if cache isa OrdinaryDiffEqMutableCache - @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache.tab - else - @unpack r14, r13, r12, r34, r33, r32, r44, r43, r42, r54, r53, r52, r64, r63, r62 = cache - end -end - -@def owrenzen4pre0 begin - @owrenzen4unpack - Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14) - b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) - b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) - b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) - b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ) - return @inbounds y₀ + - dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + - # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ) - return y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - @inbounds @.. broadcast=false out=y₀ + - dt * - (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ) - #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ) - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen4pre0 - @inbounds @.. broadcast=false out=y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + - k[6][idxs] * b6Θ) - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ) - #end - out -end - -@def owrenzen4pre1 begin - @owrenzen4unpack - b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14) - b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34) - b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44) - b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54) - b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @inbounds @.. broadcast=false k[1]*b1Θdiff+k[3]*b3Θdiff+k[4]*b4Θdiff+k[5]*b5Θdiff+ - k[6]*b6Θdiff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @views @.. broadcast=false k[1][idxs]*b1Θdiff+k[3][idxs]*b3Θdiff+k[4][idxs]*b4Θdiff+ - k[5][idxs]*b5Θdiff+k[6][idxs]*b6Θdiff -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + k[6] * b6Θdiff - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen4pre1 - @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff - out -end - -@def owrenzen4pre2 begin - @owrenzen4unpack - b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14) - b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34) - b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44) - b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54) - b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64) - invdt = inv(dt) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @.. broadcast=false (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2)*invdt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2)*invdt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2) * invdt - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen4pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2) * invdt - out -end - -@def owrenzen4pre3 begin - @owrenzen4unpack - b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14) - b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34) - b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44) - b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54) - b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64) - invdt2 = inv(dt)^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @inbounds @.. broadcast=false (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3)*invdt2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3)*invdt2 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3) * invdt2 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen4pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3) * invdt2 - out -end - -@def owrenzen4pre4 begin - @owrenzen4unpack - b1Θdiff4 = 24 * r14 - b3Θdiff4 = 24 * r34 - b4Θdiff4 = 24 * r44 - b5Θdiff4 = 24 * r54 - b6Θdiff4 = 24 * r64 - invdt3 = inv(dt)^3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @.. broadcast=false (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4)*invdt3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @views @.. broadcast=false (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4)*invdt3 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4) * invdt3 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen4ConstantCache, OwrenZen4Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen4pre4 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4) * invdt3 - out -end - -@def owrenzen5unpack begin - if cache isa OrdinaryDiffEqMutableCache - @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache.tab - else - @unpack r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, r43, r42, r55, r54, r53, r52, r65, r64, r63, r62, r75, r74, r73, r72, r85, r84, r83, r82 = cache - end -end - -@def owrenzen5pre0 begin - @owrenzen5unpack - Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, 1, r12, r13, r14, r15) - b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34, r35) - b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44, r45) - b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54, r55) - b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64, r65) - b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74, r75) - b8Θ = Θ² * @evalpoly(Θ, r82, r83, r84, r85) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 - # return @.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + - # k[7]*b7Θ + k[8]*b8Θ) - return @inbounds y₀ + - dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + k[6] * b6Θ + - k[7] * b7Θ + k[8] * b8Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 - # return @.. broadcast=false y₀[idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + - # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + - # k[7][idxs]*b7Θ + k[8][idxs]*b8Θ) - return y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + - k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 - @inbounds @.. broadcast=false out=y₀ + - dt * - (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ + - k[7] * b7Θ + k[8] * b8Θ) - #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{0}}, differential_vars::Nothing) - @owrenzen5pre0 - @views @.. broadcast=false out=y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + - k[7][idxs] * b7Θ + k[8][idxs] * b8Θ) - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + - # k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ) - #end - out -end - -@def owrenzen5pre1 begin - @owrenzen5unpack - b1Θdiff = @evalpoly(Θ, 1, 2*r12, 3*r13, 4*r14, 5*r15) - b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34, 5*r35) - b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44, 5*r45) - b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54, 5*r55) - b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64, 5*r65) - b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74, 5*r75) - b8Θdiff = Θ * @evalpoly(Θ, 2*r82, 3*r83, 4*r84, 5*r85) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - return @inbounds k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + k[5] * b5Θdiff + - k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + - k[6][idxs] * b6Θdiff + k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff + - k[8] * b8Θdiff - #@inbounds for i in eachindex(out) - # out[i] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + - # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{1}}, differential_vars::Nothing) - @owrenzen5pre1 - @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + - # k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff - #end - out -end - -@def owrenzen5pre2 begin - @owrenzen5unpack - b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14, 20*r15) - b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34, 20*r35) - b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44, 20*r45) - b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54, 20*r55) - b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64, 20*r65) - b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74, 20*r75) - b8Θdiff2 = @evalpoly(Θ, 2*r82, 6*r83, 12*r84, 20*r85) - invdt = inv(dt) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - return @inbounds (k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + - k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + k[8] * b8Θdiff2) * invdt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - (k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + - k[6][idxs] * b6Θdiff2 + k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[3] * b3Θdiff2 + k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2 + - k[8] * b8Θdiff2) * invdt - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + - # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{2}}, differential_vars::Nothing) - @owrenzen5pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + - k[7][idxs] * b7Θdiff2 + k[8][idxs] * b8Θdiff2) * invdt - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + - # k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2 + k[8][i]*b8Θdiff2)*invdt - #end - out -end - -@def owrenzen5pre3 begin - @owrenzen5unpack - b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14, 60*r15) - b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34, 60*r35) - b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44, 60*r45) - b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54, 60*r55) - b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64, 60*r65) - b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74, 60*r75) - b8Θdiff3 = @evalpoly(Θ, 6*r83, 24*r84, 60*r85) - invdt2 = inv(dt)^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - return @inbounds (k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + - k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + k[8] * b8Θdiff3) * invdt2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - (k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + - k[6][idxs] * b6Θdiff3 + k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[3] * b3Θdiff3 + k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3 + - k[8] * b8Θdiff3) * invdt2 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + - # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{3}}, differential_vars::Nothing) - @owrenzen5pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + - k[7][idxs] * b7Θdiff3 + k[8][idxs] * b8Θdiff3) * invdt2 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + - # k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3 + k[8][i]*b8Θdiff3)*invdt2 - #end - out -end - -@def owrenzen5pre4 begin - @owrenzen5unpack - b1Θdiff4 = @evalpoly(Θ, 24*r14, 120*r15) - b3Θdiff4 = @evalpoly(Θ, 24*r34, 120*r35) - b4Θdiff4 = @evalpoly(Θ, 24*r44, 120*r45) - b5Θdiff4 = @evalpoly(Θ, 24*r54, 120*r55) - b6Θdiff4 = @evalpoly(Θ, 24*r64, 120*r65) - b7Θdiff4 = @evalpoly(Θ, 24*r74, 120*r75) - b8Θdiff4 = @evalpoly(Θ, 24*r84, 120*r85) - invdt3 = inv(dt)^3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - return @inbounds (k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + - k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + k[8] * b8Θdiff4) * invdt3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - (k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + - k[6][idxs] * b6Θdiff4 + k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[3] * b3Θdiff4 + k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4 + - k[8] * b8Θdiff4) * invdt3 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + - # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{4}}, differential_vars::Nothing) - @owrenzen5pre4 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + - k[7][idxs] * b7Θdiff4 + k[8][idxs] * b8Θdiff4) * invdt3 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + - # k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4 + k[8][i]*b8Θdiff4)*invdt3 - #end - out -end - -@def owrenzen5pre5 begin - @owrenzen5unpack - b1Θdiff5 = 120 * r15 - b3Θdiff5 = 120 * r35 - b4Θdiff5 = 120 * r45 - b5Θdiff5 = 120 * r55 - b6Θdiff5 = 120 * r65 - b7Θdiff5 = 120 * r75 - b8Θdiff5 = 120 * r85 - invdt4 = inv(dt)^4 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - return @inbounds (k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + - k[5] * b5Θdiff5 + - k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + k[8] * b8Θdiff5) * invdt4 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - (k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + k[4][idxs] * b4Θdiff5 + - k[5][idxs] * b5Θdiff5 + - k[6][idxs] * b6Θdiff5 + k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs::Nothing, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff5 + k[3] * b3Θdiff5 + k[4] * b4Θdiff5 + - k[5] * b5Θdiff5 + k[6] * b6Θdiff5 + k[7] * b7Θdiff5 + - k[8] * b8Θdiff5) * invdt4 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + - # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{OwrenZen5ConstantCache, OwrenZen5Cache}, - idxs, T::Type{Val{5}}, differential_vars::Nothing) - @owrenzen5pre5 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff5 + k[3][idxs] * b3Θdiff5 + - k[4][idxs] * b4Θdiff5 + - k[5][idxs] * b5Θdiff5 + k[6][idxs] * b6Θdiff5 + - k[7][idxs] * b7Θdiff5 + k[8][idxs] * b8Θdiff5) * invdt4 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff5 + k[3][i]*b3Θdiff5 + k[4][i]*b4Θdiff5 + - # k[5][i]*b5Θdiff5 + k[6][i]*b6Θdiff5 + k[7][i]*b7Θdiff5 + k[8][i]*b8Θdiff5)*invdt4 - #end - out -end - -@def bs5unpack begin - if cache isa OrdinaryDiffEqMutableCache - @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache.tab - else - @unpack r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = cache - end -end - -@def bs5pre0 begin - @bs5unpack - Θ² = Θ * Θ - b1Θ = Θ² * @evalpoly(Θ, r012, r013, r014, r015, r016) - b3Θ = Θ² * @evalpoly(Θ, r032, r033, r034, r035, r036) - b4Θ = Θ² * @evalpoly(Θ, r042, r043, r044, r045, r046) - b5Θ = Θ² * @evalpoly(Θ, r052, r053, r054, r055, r056) - b6Θ = Θ² * @evalpoly(Θ, r062, r063, r064, r065, r066) - b7Θ = Θ² * @evalpoly(Θ, r072, r073, r074, r075, r076) - b8Θ = Θ² * @evalpoly(Θ, r082, r083, r084, r085, r086) - b9Θ = (Θ² * Θ) * @evalpoly(Θ, r093, r094, r095, - r096) - b10Θ = Θ² * @evalpoly(Θ, r102, r103, r104, r105, r106) - b11Θ = Θ² * @evalpoly(Θ, r112, r113, r114, r115, r116) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5ConstantCache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) - return @inbounds y₀ + dt * Θ * k[1] + - dt * (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + k[10] * b10Θ + - k[11] * b11Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::BS5Cache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - # return @.. broadcast=false y₀ + dt*Θ*k[1] + dt*(k[1]*b1Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ + k[8]*b8Θ + k[9]*b9Θ + k[10]*b10Θ + k[11]*b11Θ) - return @inbounds @.. broadcast=false y₀+dt*Θ*k[1]+ - dt*(k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + - k[5] * b5Θ + - k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + - k[9] * b9Θ + k[10] * b10Θ + k[11] * b11Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - # return @.. broadcast=false y₀[idxs] + dt*Θ*k[1][idxs] + dt*(k[1][idxs]*b1Θ + k[3][idxs]*b3Θ + - # k[4][idxs]*b4Θ + k[5][idxs]*b5Θ + k[6][idxs]*b6Θ + k[7][idxs]*b7Θ + - # k[8][idxs]*b8Θ + k[9][idxs]*b9Θ + k[10][idxs]*b10Θ + k[11][idxs]*b11Θ) - return y₀[idxs] + dt * Θ * k[1][idxs] + - dt * (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + - k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - @inbounds @.. broadcast=false out=y₀ + dt * Θ * k[1] + - dt * - (k[1] * b1Θ + k[3] * b3Θ + k[4] * b4Θ + k[5] * b5Θ + - k[6] * b6Θ + k[7] * b7Θ + k[8] * b8Θ + k[9] * b9Θ + - k[10] * b10Θ + k[11] * b11Θ) - #@inbounds for i in eachindex(out) - # out[i] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @bs5pre0 - @views @.. broadcast=false out=y₀[idxs] + dt * Θ * k[1][idxs] + - dt * - (k[1][idxs] * b1Θ + k[3][idxs] * b3Θ + k[4][idxs] * b4Θ + - k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ + - k[8][idxs] * b8Θ + k[9][idxs] * b9Θ + - k[10][idxs] * b10Θ + k[11][idxs] * b11Θ) - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*Θ*k[1][i] + dt*(k[1][i]*b1Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ + k[8][i]*b8Θ + k[9][i]*b9Θ + k[10][i]*b10Θ + k[11][i]*b11Θ) - #end - out -end - -@def bs5pre1 begin - @bs5unpack - Θ² = Θ * Θ - b1Θdiff = Θ * @evalpoly(Θ, 2*r012, 3*r013, 4*r014, 5*r015, 6*r016) - b3Θdiff = Θ * @evalpoly(Θ, 2*r032, 3*r033, 4*r034, 5*r035, 6*r036) - b4Θdiff = Θ * @evalpoly(Θ, 2*r042, 3*r043, 4*r044, 5*r045, 6*r046) - b5Θdiff = Θ * @evalpoly(Θ, 2*r052, 3*r053, 4*r054, 5*r055, 6*r056) - b6Θdiff = Θ * @evalpoly(Θ, 2*r062, 3*r063, 4*r064, 5*r065, 6*r066) - b7Θdiff = Θ * @evalpoly(Θ, 2*r072, 3*r073, 4*r074, 5*r075, 6*r076) - b8Θdiff = Θ * @evalpoly(Θ, 2*r082, 3*r083, 4*r084, 5*r085, 6*r086) - b9Θdiff = Θ² * @evalpoly(Θ, 3*r093, 4*r094, 5*r095, 6*r096) - b10Θdiff = Θ * @evalpoly(Θ, 2*r102, 3*r103, 4*r104, 5*r105, 6*r106) - b11Θdiff = Θ * @evalpoly(Θ, 2*r112, 3*r113, 4*r114, 5*r115, 6*r116) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - # return @.. broadcast=false k[1] + k[1]*b1Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff + k[8]*b8Θdiff + k[9]*b9Θdiff + k[10]*b10Θdiff + k[11]*b11Θdiff - return @inbounds k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + - k[6] * b6Θdiff + k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + - k[10] * b10Θdiff + k[11] * b11Θdiff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - # return @.. broadcast=false k[1][idxs] + k[1][idxs]*b1Θdiff + k[3][idxs]*b3Θdiff + - # k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + - # k[7][idxs]*b7Θdiff + k[8][idxs]*b8Θdiff + k[9][idxs]*b9Θdiff + - # k[10][idxs]*b10Θdiff + k[11][idxs]*b11Θdiff - return @inbounds k[1][idxs] + k[1][idxs] * b1Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + k[9][idxs] * b9Θdiff + - k[10][idxs] * b10Θdiff + k[11][idxs] * b11Θdiff -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - @inbounds @.. broadcast=false out=k[1] + k[1] * b1Θdiff + k[3] * b3Θdiff + - k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + - k[7] * b7Θdiff + k[8] * b8Θdiff + k[9] * b9Θdiff + - k[10] * b10Θdiff + k[11] * b11Θdiff - #@inbounds for i in eachindex(out) - # out[i] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{BS5ConstantCache, BS5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @bs5pre1 - @views @.. broadcast=false out=k[1][idxs] + k[1][idxs] * b1Θdiff + - k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff + k[8][idxs] * b8Θdiff + - k[9][idxs] * b9Θdiff + k[10][idxs] * b10Θdiff + - k[11][idxs] * b11Θdiff - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = k[1][i] + k[1][i]*b1Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff + k[8][i]*b8Θdiff + k[9][i]*b9Θdiff + k[10][i]*b10Θdiff + k[11][i]*b11Θdiff - #end - out -end - -@def dp5pre0 begin - b10 = Θ - b20 = Θ * (1 - Θ) - b30 = Θ * b20 - b40 = b20^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5ConstantCache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 - @inbounds y₀ + dt * (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::DP5Cache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 - @inbounds @.. broadcast=false y₀+dt * - (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 - @views @.. broadcast=false y₀[idxs]+dt * (k[1][idxs] * b10 + k[2][idxs] * b20 + - k[3][idxs] * b30 + k[4][idxs] * b40) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 - @inbounds @.. broadcast=false out=y₀ + - dt * - (k[1] * b10 + k[2] * b20 + k[3] * b30 + k[4] * b40) - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @dp5pre0 - @views @.. broadcast=false out=y₀[idxs] + - dt * - (k[1][idxs] * b10 + k[2][idxs] * b20 + k[3][idxs] * b30 + - k[4][idxs] * b40) - out -end - -@def dp5pre1 begin - b20diff = @evalpoly(Θ, 1, -2) - b30diff = Θ * @evalpoly(Θ, 2, -3) - b40diff = Θ * @evalpoly(Θ, 2, -6, 4) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @inbounds @.. broadcast=false k[1]+k[2]*b20diff+k[3]*b30diff+k[4]*b40diff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @views @.. broadcast=false k[1][idxs]+k[2][idxs]*b20diff+k[3][idxs]*b30diff+ - k[4][idxs]*b40diff -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @inbounds @.. broadcast=false out=k[1] + k[2] * b20diff + k[3] * b30diff + - k[4] * b40diff - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @dp5pre1 - @views @.. broadcast=false out=k[1][idxs] + k[2][idxs] * b20diff + - k[3][idxs] * b30diff + k[4][idxs] * b40diff - out -end - -@def dp5pre2 begin - b20diff2 = -2 - b30diff2 = @evalpoly(Θ, 2, -6) - b40diff2 = @evalpoly(Θ, 2, -12, 12) - invdt = inv(dt) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @inbounds @.. broadcast=false (k[2] * b20diff2 + k[3] * b30diff2 + - k[4] * b40diff2)*invdt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @views @.. broadcast=false (k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + - k[4][idxs] * b40diff2)*invdt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @inbounds @.. broadcast=false out=(k[2] * b20diff2 + k[3] * b30diff2 + - k[4] * b40diff2) * - invdt - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @dp5pre2 - @views @.. broadcast=false out=(k[2][idxs] * b20diff2 + k[3][idxs] * b30diff2 + - k[4][idxs] * b40diff2) * invdt - out -end - -@def dp5pre3 begin - b30diff3 = -6 - b40diff3 = @evalpoly(Θ, -12, 24) - invdt2 = inv(dt)^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @inbounds @.. broadcast=false (k[3] * b30diff3 + k[4] * b40diff3)*invdt2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @views @.. broadcast=false (k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3)*invdt2 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @inbounds @.. broadcast=false out=(k[3] * b30diff3 + k[4] * b40diff3) * invdt2 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @dp5pre3 - @views @.. broadcast=false out=(k[3][idxs] * b30diff3 + k[4][idxs] * b40diff3) * invdt2 - out -end - -@def dp5pre4 begin - b40diff4invdt3 = 24 * inv(dt)^3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @inbounds @.. broadcast=false k[4]*b40diff4invdt3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @views @.. broadcast=false k[4][idxs]*b40diff4invdt3 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs::Nothing, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @inbounds @.. broadcast=false out=k[4] * b40diff4invdt3 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{DP5ConstantCache, DP5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @dp5pre4 - @views @.. broadcast=false out=k[4][idxs] * b40diff4invdt3 - out -end - -@def tsit5unpack begin - var"#T#" = constvalue(recursive_unitless_bottom_eltype(y₁)) - r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, r62, r63, r64, r72, r73, r74 = Tsit5Interp(var"#T#") -end - -@def tsit5pre0 begin - @tsit5unpack - Θ² = Θ * Θ - b1Θ = Θ * @evalpoly(Θ, r11, r12, r13, r14) - b2Θ = Θ² * @evalpoly(Θ, r22, r23, r24) - b3Θ = Θ² * @evalpoly(Θ, r32, r33, r34) - b4Θ = Θ² * @evalpoly(Θ, r42, r43, r44) - b5Θ = Θ² * @evalpoly(Θ, r52, r53, r54) - b6Θ = Θ² * @evalpoly(Θ, r62, r63, r64) - b7Θ = Θ² * @evalpoly(Θ, r72, r73, r74) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - #@.. broadcast=false y₀ + dt*(k[1]*b1Θ + k[2]*b2Θ + k[3]*b3Θ + k[4]*b4Θ + k[5]*b5Θ + k[6]*b6Θ + k[7]*b7Θ) - return @inbounds y₀ + - dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + - k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - return @inbounds @.. broadcast=false y₀+dt * (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + - k[4] * b4Θ + - k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - return y₀[idxs] + - dt * (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + k[7][idxs] * b7Θ) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - @inbounds @.. broadcast=false out=y₀ + - dt * - (k[1] * b1Θ + k[2] * b2Θ + k[3] * b3Θ + k[4] * b4Θ + - k[5] * b5Θ + k[6] * b6Θ + k[7] * b7Θ) - out -end - -@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - @inbounds @simd ivdep for i in eachindex(out) - out[i] = y₀[i] + - dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + - k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) - end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - @views @.. broadcast=false out=y₀[idxs] + - dt * - (k[1][idxs] * b1Θ + k[2][idxs] * b2Θ + k[3][idxs] * b3Θ + - k[4][idxs] * b4Θ + k[5][idxs] * b5Θ + k[6][idxs] * b6Θ + - k[7][idxs] * b7Θ) - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = y₀[i] + dt*(k[1][i]*b1Θ + k[2][i]*b2Θ + k[3][i]*b3Θ + k[4][i]*b4Θ + k[5][i]*b5Θ + k[6][i]*b6Θ + k[7][i]*b7Θ) - #end - out -end - -@muladd function _ode_interpolant!(out::Array, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{0}}, differential_vars::Nothing) - @tsit5pre0 - @inbounds for (j, i) in enumerate(idxs) - out[j] = y₀[i] + - dt * (k[1][i] * b1Θ + k[2][i] * b2Θ + k[3][i] * b3Θ + k[4][i] * b4Θ + - k[5][i] * b5Θ + k[6][i] * b6Θ + k[7][i] * b7Θ) - end - out -end - -@def tsit5pre1 begin - @tsit5unpack - b1Θdiff = @evalpoly(Θ, r11, 2*r12, 3*r13, 4*r14) - b2Θdiff = Θ * @evalpoly(Θ, 2*r22, 3*r23, 4*r24) - b3Θdiff = Θ * @evalpoly(Θ, 2*r32, 3*r33, 4*r34) - b4Θdiff = Θ * @evalpoly(Θ, 2*r42, 3*r43, 4*r44) - b5Θdiff = Θ * @evalpoly(Θ, 2*r52, 3*r53, 4*r54) - b6Θdiff = Θ * @evalpoly(Θ, 2*r62, 3*r63, 4*r64) - b7Θdiff = Θ * @evalpoly(Θ, 2*r72, 3*r73, 4*r74) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5ConstantCache, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - # return @.. broadcast=false k[1]*b1Θdiff + k[2]*b2Θdiff + k[3]*b3Θdiff + k[4]*b4Θdiff + k[5]*b5Θdiff + k[6]*b6Θdiff + k[7]*b7Θdiff - return @inbounds k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + k[4] * b4Θdiff + - k[5] * b5Θdiff + k[6] * b6Θdiff + k[7] * b7Θdiff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Tsit5Cache, idxs::Nothing, - T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - return @inbounds @.. broadcast=false k[1]*b1Θdiff+k[2]*b2Θdiff+k[3]*b3Θdiff+ - k[4]*b4Θdiff+k[5]*b5Θdiff+k[6]*b6Θdiff+k[7]*b7Θdiff -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - # return @.. broadcast=false k[1][idxs]*b1Θdiff + k[2][idxs]*b2Θdiff + k[3][idxs]*b3Θdiff + k[4][idxs]*b4Θdiff + k[5][idxs]*b5Θdiff + k[6][idxs]*b6Θdiff + k[7][idxs]*b7Θdiff - return k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + k[3][idxs] * b3Θdiff + - k[4][idxs] * b4Θdiff + k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - @inbounds @.. broadcast=false out=k[1] * b1Θdiff + k[2] * b2Θdiff + k[3] * b3Θdiff + - k[4] * b4Θdiff + k[5] * b5Θdiff + k[6] * b6Θdiff + - k[7] * b7Θdiff - #@inbounds for i in eachindex(out) - # out[i] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{1}}, differential_vars::Nothing) - @tsit5pre1 - @views @.. broadcast=false out=k[1][idxs] * b1Θdiff + k[2][idxs] * b2Θdiff + - k[3][idxs] * b3Θdiff + k[4][idxs] * b4Θdiff + - k[5][idxs] * b5Θdiff + k[6][idxs] * b6Θdiff + - k[7][idxs] * b7Θdiff - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = k[1][i]*b1Θdiff + k[2][i]*b2Θdiff + k[3][i]*b3Θdiff + k[4][i]*b4Θdiff + k[5][i]*b5Θdiff + k[6][i]*b6Θdiff + k[7][i]*b7Θdiff - #end - out -end - -@def tsit5pre2 begin - @tsit5unpack - b1Θdiff2 = @evalpoly(Θ, 2*r12, 6*r13, 12*r14) - b2Θdiff2 = @evalpoly(Θ, 2*r22, 6*r23, 12*r24) - b3Θdiff2 = @evalpoly(Θ, 2*r32, 6*r33, 12*r34) - b4Θdiff2 = @evalpoly(Θ, 2*r42, 6*r43, 12*r44) - b5Θdiff2 = @evalpoly(Θ, 2*r52, 6*r53, 12*r54) - b6Θdiff2 = @evalpoly(Θ, 2*r62, 6*r63, 12*r64) - b7Θdiff2 = @evalpoly(Θ, 2*r72, 6*r73, 12*r74) - invdt = inv(dt) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - # return @.. broadcast=false k[1]*b1Θdiff2 + k[2]*b2Θdiff2 + k[3]*b3Θdiff2 + k[4]*b4Θdiff2 + k[5]*b5Θdiff2 + k[6]*b6Θdiff2 + k[7]*b7Θdiff2 - return @inbounds (k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2 + - k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + k[7] * b7Θdiff2) * invdt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - # return @.. broadcast=false k[1][idxs]*b1Θdiff2 + k[2][idxs]*b2Θdiff2 + k[3][idxs]*b3Θdiff2 + k[4][idxs]*b4Θdiff2 + k[5][idxs]*b5Θdiff2 + k[6][idxs]*b6Θdiff2 + k[7][idxs]*b7Θdiff2 - return (k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + k[3][idxs] * b3Θdiff2 + - k[4][idxs] * b4Θdiff2 + k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + - k[7][idxs] * b7Θdiff2) * invdt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff2 + k[2] * b2Θdiff2 + k[3] * b3Θdiff2 + - k[4] * b4Θdiff2 + k[5] * b5Θdiff2 + k[6] * b6Θdiff2 + - k[7] * b7Θdiff2) * invdt - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{2}}, differential_vars::Nothing) - @tsit5pre2 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff2 + k[2][idxs] * b2Θdiff2 + - k[3][idxs] * b3Θdiff2 + k[4][idxs] * b4Θdiff2 + - k[5][idxs] * b5Θdiff2 + k[6][idxs] * b6Θdiff2 + - k[7][idxs] * b7Θdiff2) * invdt - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff2 + k[2][i]*b2Θdiff2 + k[3][i]*b3Θdiff2 + k[4][i]*b4Θdiff2 + k[5][i]*b5Θdiff2 + k[6][i]*b6Θdiff2 + k[7][i]*b7Θdiff2)*invdt - #end - out -end - -@def tsit5pre3 begin - @tsit5unpack - b1Θdiff3 = @evalpoly(Θ, 6*r13, 24*r14) - b2Θdiff3 = @evalpoly(Θ, 6*r23, 24*r24) - b3Θdiff3 = @evalpoly(Θ, 6*r33, 24*r34) - b4Θdiff3 = @evalpoly(Θ, 6*r43, 24*r44) - b5Θdiff3 = @evalpoly(Θ, 6*r53, 24*r54) - b6Θdiff3 = @evalpoly(Θ, 6*r63, 24*r64) - b7Θdiff3 = @evalpoly(Θ, 6*r73, 24*r74) - invdt2 = inv(dt)^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - # return @.. broadcast=false k[1]*b1Θdiff3 + k[2]*b2Θdiff3 + k[3]*b3Θdiff3 + k[4]*b4Θdiff3 + k[5]*b5Θdiff3 + k[6]*b6Θdiff3 + k[7]*b7Θdiff3 - return @inbounds (k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3 + - k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + k[7] * b7Θdiff3) * invdt2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - # return @.. broadcast=false k[1][idxs]*b1Θdiff3 + k[2][idxs]*b2Θdiff3 + k[3][idxs]*b3Θdiff3 + k[4][idxs]*b4Θdiff3 + k[5][idxs]*b5Θdiff3 + k[6][idxs]*b6Θdiff3 + k[7][idxs]*b7Θdiff3 - return (k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + k[3][idxs] * b3Θdiff3 + - k[4][idxs] * b4Θdiff3 + k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + - k[7][idxs] * b7Θdiff3) * invdt2 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff3 + k[2] * b2Θdiff3 + k[3] * b3Θdiff3 + - k[4] * b4Θdiff3 + k[5] * b5Θdiff3 + k[6] * b6Θdiff3 + - k[7] * b7Θdiff3) * invdt2 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{3}}, differential_vars::Nothing) - @tsit5pre3 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff3 + k[2][idxs] * b2Θdiff3 + - k[3][idxs] * b3Θdiff3 + k[4][idxs] * b4Θdiff3 + - k[5][idxs] * b5Θdiff3 + k[6][idxs] * b6Θdiff3 + - k[7][idxs] * b7Θdiff3) * invdt2 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff3 + k[2][i]*b2Θdiff3 + k[3][i]*b3Θdiff3 + k[4][i]*b4Θdiff3 + k[5][i]*b5Θdiff3 + k[6][i]*b6Θdiff3 + k[7][i]*b7Θdiff3)*invdt2 - #end - out -end - -@def tsit5pre4 begin - @tsit5unpack - b1Θdiff4 = 24 * r14 - b2Θdiff4 = 24 * r24 - b3Θdiff4 = 24 * r34 - b4Θdiff4 = 24 * r44 - b5Θdiff4 = 24 * r54 - b6Θdiff4 = 24 * r64 - b7Θdiff4 = 24 * r74 - invdt3 = inv(dt)^3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - # return @.. broadcast=false k[1]*b1Θdiff4 + k[2]*b2Θdiff4 + k[3]*b3Θdiff4 + k[4]*b4Θdiff4 + k[5]*b5Θdiff4 + k[6]*b6Θdiff4 + k[7]*b7Θdiff4 - return @inbounds (k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + - k[4] * b4Θdiff4 + - k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + k[7] * b7Θdiff4) * invdt3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - # return @.. broadcast=false k[1][idxs]*b1Θdiff4 + k[2][idxs]*b2Θdiff4 + k[3][idxs]*b3Θdiff4 + k[4][idxs]*b4Θdiff4 + k[5][idxs]*b5Θdiff4 + k[6][idxs]*b6Θdiff4 + k[7][idxs]*b7Θdiff4 - return (k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + k[3][idxs] * b3Θdiff4 + - k[4][idxs] * b4Θdiff4 + k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + - k[7][idxs] * b7Θdiff4) * invdt3 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, - idxs::Nothing, T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - @inbounds @.. broadcast=false out=(k[1] * b1Θdiff4 + k[2] * b2Θdiff4 + k[3] * b3Θdiff4 + - k[4] * b4Θdiff4 + k[5] * b5Θdiff4 + k[6] * b6Θdiff4 + - k[7] * b7Θdiff4) * invdt3 - #@inbounds for i in eachindex(out) - # out[i] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 - #end - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Tsit5ConstantCache, Tsit5Cache}, idxs, - T::Type{Val{4}}, differential_vars::Nothing) - @tsit5pre4 - @views @.. broadcast=false out=(k[1][idxs] * b1Θdiff4 + k[2][idxs] * b2Θdiff4 + - k[3][idxs] * b3Θdiff4 + k[4][idxs] * b4Θdiff4 + - k[5][idxs] * b5Θdiff4 + k[6][idxs] * b6Θdiff4 + - k[7][idxs] * b7Θdiff4) * invdt3 - #@inbounds for (j,i) in enumerate(idxs) - # out[j] = (k[1][i]*b1Θdiff4 + k[2][i]*b2Θdiff4 + k[3][i]*b3Θdiff4 + k[4][i]*b4Θdiff4 + k[5][i]*b5Θdiff4 + k[6][i]*b6Θdiff4 + k[7][i]*b7Θdiff4)*invdt3 - #end - out -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_addsteps.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_addsteps.jl deleted file mode 100644 index 9e609808b1..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_addsteps.jl +++ /dev/null @@ -1,715 +0,0 @@ -function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::FunctionMapCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - nothing -end - -function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::FunctionMapConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - nothing -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::OwrenZen4Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 6 || always_calc_begin - uidx = eachindex(uprev) - @unpack k1, k2, k3, k4, k5, k6, tmp = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4 = cache.tab - # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. - a = dt * a21 - @.. broadcast=false tmp=uprev + a * k1 - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - f(k5, tmp, p, t + c4 * dt) - # NOTE: We should not change u here. - @.. broadcast=false tmp=uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - f(k6, tmp, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - copyat_or_push!(k, 5, k5) - copyat_or_push!(k, 6, k6) - end - nothing -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::OwrenZen5Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 8 || always_calc_begin - uidx = eachindex(uprev) - @unpack k1, k2, k3, k4, k5, k6, k7, k8, tmp = cache - @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6 = cache.tab - # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. - a = dt * a21 - @.. broadcast=false tmp=uprev + a * k1 - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + k3) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - f(k6, tmp, p, t + c5 * dt) - @.. broadcast=false tmp=uprev + - dt * - (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + - a76 * k6) - f(k7, tmp, p, t + c6 * dt) - # NOTE: We should not change u here. - @.. broadcast=false tmp=uprev + - dt * - (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + - a87 * k7) - f(k8, tmp, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - copyat_or_push!(k, 5, k5) - copyat_or_push!(k, 6, k6) - copyat_or_push!(k, 7, k7) - copyat_or_push!(k, 8, k8) - end - nothing -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP5Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 4 || always_calc_begin - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract DP5ConstantCacheActual T T2 - @unpack k1, k2, k3, k4, k5, k6, k7, dense_tmp3, dense_tmp4, update, bspl, utilde, tmp, atmp = cache - uidx = eachindex(uprev) - f(k1, uprev, p, t) - @.. broadcast=false tmp=uprev + dt * (a21 * k1) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - f(k6, tmp, p, t + dt) - @.. broadcast=false update=a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6 - @.. broadcast=false tmp=uprev + dt * update - f(k7, tmp, p, t + dt) - copyat_or_push!(k, 1, update) - @.. broadcast=false utilde=dt * (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + btilde7 * k7) - #integrator.k[4] == k5 - @.. broadcast=false k5=d1 * k1 + d3 * k3 + d4 * k4 + d5 * k5 + d6 * k6 + d7 * k7 - #bspl == k3 - @.. broadcast=false bspl=k1 - update - # k6 === integrator.k[3] === k2 - @.. broadcast=false k6=update - k7 - bspl - copyat_or_push!(k, 2, bspl) - copyat_or_push!(k, 3, k6) - copyat_or_push!(k, 4, k5) - end - nothing -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Tsit5Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 7 || always_calc_begin - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 - @unpack k1, k2, k3, k4, k5, k6, k7, tmp = cache - @.. broadcast=false tmp=uprev + dt * (a21 * k1) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - f(k6, tmp, p, t + dt) - @.. broadcast=false tmp=uprev + - dt * - (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + - a76 * k6) - f(k7, tmp, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - copyat_or_push!(k, 5, k5) - copyat_or_push!(k, 6, k6) - copyat_or_push!(k, 7, k7) - end - nothing -end - -""" -An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine -Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 - -Called to add the extra k9, k10, k11 steps for the Order 5 interpolation when needed -""" -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::BS5Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 8 || always_calc_begin - uidx = eachindex(uprev) - @unpack k1, k2, k3, k4, k5, k6, k7, k8, tmp = cache - @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87 = cache.tab - @.. broadcast=false tmp=uprev + dt * a21 * k1 - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false tmp=uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - f(k6, tmp, p, t + c5 * dt) - @.. broadcast=false tmp=uprev + - dt * - (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + - a76 * k6) - f(k7, tmp, p, t + dt) - @.. broadcast=false tmp=uprev + - dt * - (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + - a87 * k7) - f(k8, tmp, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - copyat_or_push!(k, 5, k5) - copyat_or_push!(k, 6, k6) - copyat_or_push!(k, 7, k7) - copyat_or_push!(k, 8, k8) - end - if (allow_calc_end && length(k) < 11) || force_calc_end # Have not added the extra stages yet - uidx = eachindex(uprev) - rtmp = similar(cache.k1) - @unpack tmp = cache - @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache.tab - @.. broadcast=false tmp=uprev + - dt * (a91 * k[1] + a92 * k[2] + a93 * k[3] + a94 * k[4] + - a95 * k[5] + a96 * k[6] + a97 * k[7] + a98 * k[8]) - f(rtmp, tmp, p, t + c6 * dt) - copyat_or_push!(k, 9, rtmp) - @.. broadcast=false tmp=uprev + - dt * - (a101 * k[1] + a102 * k[2] + a103 * k[3] + a104 * k[4] + - a105 * k[5] + a106 * k[6] + a107 * k[7] + a108 * k[8] + - a109 * k[9]) - f(rtmp, tmp, p, t + c7 * dt) - copyat_or_push!(k, 10, rtmp) - @.. broadcast=false tmp=uprev + - dt * - (a111 * k[1] + a112 * k[2] + a113 * k[3] + a114 * k[4] + - a115 * k[5] + a116 * k[6] + a117 * k[7] + a118 * k[8] + - a119 * k[9] + a1110 * k[10]) - f(rtmp, tmp, p, t + c8 * dt) - copyat_or_push!(k, 11, rtmp) - end - nothing -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, - cache::OwrenZen3ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 4 || always_calc_begin - @unpack a21, a31, a32, a41, a42, a43, c1, c2 = cache - k1 = f(uprev, p, t) - a1 = dt * a21 - k2 = f(uprev + a1 * k1, p, t + c1 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c2 * dt) - u = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(u, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - end - nothing -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::OwrenZen3Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 4 || always_calc_begin - @unpack k1, k2, k3, k4, tmp = cache - @unpack a21, a31, a32, a41, a42, a43, c1, c2 = cache.tab - # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. - a1 = dt * a21 - @.. broadcast=false tmp=uprev + a1 * k1 - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false tmp=uprev + dt * (a31 * k1 + a32 * k2) - f(k3, tmp, p, t + c2 * dt) - # NOTE: We should not change u here. - @.. broadcast=false tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - f(k4, tmp, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - end - nothing -end - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, - cache::OwrenZen4ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 6 || always_calc_begin - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4 = cache - k1 = f(uprev, p, t) - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - u = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(u, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - copyat_or_push!(k, 5, k5) - copyat_or_push!(k, 6, k6) - end - nothing -end - -#= -@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::OwrenZen4Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) - if length(k)<6 || always_calc_begin - uidx = eachindex(uprev) - @unpack k1,k2,k3,k4,k5,k6,tmp = cache - @unpack a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a63,a64,a65,c1,c2,c3,c4 = cache.tab - # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. - a = dt*a21 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2,tmp,p,t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3,tmp,p,t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) - end - f(k4,tmp,p,t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5,tmp,p,t+c4*dt) - # NOTE: We should not change u here. - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6,tmp,p,t+dt) - copyat_or_push!(k,1,k1) - copyat_or_push!(k,2,k2) - copyat_or_push!(k,3,k3) - copyat_or_push!(k,4,k4) - copyat_or_push!(k,5,k5) - copyat_or_push!(k,6,k6) - end - nothing -end -=# - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, - cache::OwrenZen5ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 8 || always_calc_begin - @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6 = cache - k1 = f(uprev, p, t) - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, - t + c5 * dt) - k7 = f( - uprev + - dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), - p, - t + c6 * dt) - u = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) - k8 = f(u, p, t + dt) - copyat_or_push!(k, 1, k1) - copyat_or_push!(k, 2, k2) - copyat_or_push!(k, 3, k3) - copyat_or_push!(k, 4, k4) - copyat_or_push!(k, 5, k5) - copyat_or_push!(k, 6, k6) - copyat_or_push!(k, 7, k7) - copyat_or_push!(k, 8, k8) - end - nothing -end - -#= -@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::OwrenZen5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) - if length(k)<8 || always_calc_begin - uidx = eachindex(uprev) - @unpack k1,k2,k3,k4,k5,k6,k7,k8,tmp = cache - @unpack a21,a31,a32,a41,a42,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,c1,c2,c3,c4,c5,c6 = cache.tab - # NOTE: k1 does not need to be evaluated since it is aliased with integrator.fsalfirst. - a = dt*a21 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2,tmp,p,t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3,tmp,p,t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+k3[i]) - end - f(k4,tmp,p,t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5,tmp,p,t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6,tmp,p,t+c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) - end - f(k7,tmp,p,t+c6*dt) - # NOTE: We should not change u here. - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) - end - f(k8,tmp,p,t+dt) - copyat_or_push!(k,1,k1) - copyat_or_push!(k,2,k2) - copyat_or_push!(k,3,k3) - copyat_or_push!(k,4,k4) - copyat_or_push!(k,5,k5) - copyat_or_push!(k,6,k6) - copyat_or_push!(k,7,k7) - copyat_or_push!(k,8,k8) - end - nothing -end -=# - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::DP5ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 4 || always_calc_begin - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract DP5ConstantCacheActual T T2 - k1 = f(uprev, p, t) - k2 = f(uprev + dt * (a21 * k1), p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, - t + dt) - update = a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6 - k7 = f(uprev + dt * update, p, t + dt) - copyat_or_push!(k, 1, update) - bspl = k1 - update - copyat_or_push!(k, 2, bspl) - copyat_or_push!(k, 3, update - k7 - bspl) - copyat_or_push!(k, 4, d1 * k1 + d3 * k3 + d4 * k4 + d5 * k5 + d6 * k6 + d7 * k7) - end - nothing -end - -#= -@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::DP5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) - if length(k)<4 || always_calc_begin - @unpack a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a73,a74,a75,a76,btilde1,btilde3,btilde4,btilde5,btilde6,btilde7,c1,c2,c3,c4,c5,c6 = cache.tab - @unpack k1,k2,k3,k4,k5,k6,k7,dense_tmp3,dense_tmp4,update,bspl,utilde,tmp,atmp = cache - @unpack d1,d3,d4,d5,d6,d7 = cache.tab - uidx = eachindex(uprev) - f(k1,uprev,p,t) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a21*k1[i]) - end - f(k2,tmp,p,t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3,tmp,p,t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) - end - f(k4,tmp,p,t+c3*dt) - @tight_loop_macros for i in uidx - tmp[i] =uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5,tmp,p,t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6,tmp,p,t+dt) - @tight_loop_macros for i in uidx - @inbounds update[i] = a71*k1[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i] - @inbounds tmp[i] = uprev[i]+dt*update[i] - end - f(k7,tmp,p,t+dt) - copyat_or_push!(k,1,update) - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i] + btilde6*k6[i] + btilde7*k7[i]) - end - @tight_loop_macros for i in uidx - #integrator.k[4] == k5 - @inbounds k5[i] = d1*k1[i]+d3*k3[i]+d4*k4[i]+d5*k5[i]+d6*k6[i]+d7*k7[i] - #bspl == k3 - @inbounds bspl[i] = k1[i] - update[i] - # k6 === integrator.k[3] === k2 - @inbounds k6[i] = update[i] - k7[i] - bspl[i] - end - copyat_or_push!(k,2,bspl) - copyat_or_push!(k,3,k6) - copyat_or_push!(k,4,k5) - end - nothing -end -=# - -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Tsit5ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 7 || always_calc_begin - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 - copyat_or_push!(k, 1, f(uprev, p, t)) - copyat_or_push!(k, 2, f(uprev + dt * (a21 * k[1]), p, t + c1 * dt)) - copyat_or_push!(k, 3, f(uprev + dt * (a31 * k[1] + a32 * k[2]), p, t + c2 * dt)) - copyat_or_push!(k, 4, - f(uprev + dt * (a41 * k[1] + a42 * k[2] + a43 * k[3]), p, - t + c3 * dt)) - copyat_or_push!(k, 5, - f(uprev + dt * (a51 * k[1] + a52 * k[2] + a53 * k[3] + a54 * k[4]), - p, t + c4 * dt)) - copyat_or_push!(k, 6, - f( - uprev + - dt * - (a61 * k[1] + a62 * k[2] + a63 * k[3] + a64 * k[4] + a65 * k[5]), - p, t + dt)) - utmp = uprev + - dt * - (a71 * k[1] + a72 * k[2] + a73 * k[3] + a74 * k[4] + a75 * k[5] + a76 * k[6]) - copyat_or_push!(k, 7, f(utmp, p, t + dt)) - end - nothing -end - -#= -@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::Tsit5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) - if length(k)<7 || always_calc_begin - @unpack c1,c2,c3,c4,c5,c6,a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76 = cache.tab - @unpack k1,k2,k3,k4,k5,k6,k7,tmp = cache - uidx = eachindex(uprev) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a21*k1[i]) - end - f(k2,tmp,p,t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3,tmp,p,t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) - end - f(k4,tmp,p,t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5,tmp,p,t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6,tmp,p,t+dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) - end - f(k7,u,p,t+dt) - copyat_or_push!(k,1,k1) - copyat_or_push!(k,2,k2) - copyat_or_push!(k,3,k3) - copyat_or_push!(k,4,k4) - copyat_or_push!(k,5,k5) - copyat_or_push!(k,6,k6) - copyat_or_push!(k,7,k7) - end - nothing -end -=# - -""" -An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine -Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 - -Called to add the extra k9, k10, k11 steps for the Order 5 interpolation when needed -""" -@muladd function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::BS5ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 8 || always_calc_begin - @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87 = cache - copyat_or_push!(k, 1, f(uprev, p, t)) - copyat_or_push!(k, 2, f(uprev + dt * a21 * k[1], p, t + c1 * dt)) - copyat_or_push!(k, 3, f(uprev + dt * (a31 * k[1] + a32 * k[2]), p, t + c2 * dt)) - copyat_or_push!(k, 4, - f(uprev + dt * (a41 * k[1] + a42 * k[2] + a43 * k[3]), p, - t + c3 * dt)) - copyat_or_push!(k, 5, - f(uprev + dt * (a51 * k[1] + a52 * k[2] + a53 * k[3] + a54 * k[4]), - p, t + c4 * dt)) - copyat_or_push!(k, 6, - f( - uprev + - dt * - (a61 * k[1] + a62 * k[2] + a63 * k[3] + a64 * k[4] + a65 * k[5]), - p, t + c5 * dt)) - copyat_or_push!(k, 7, - f( - uprev + - dt * - (a71 * k[1] + a72 * k[2] + a73 * k[3] + a74 * k[4] + a75 * k[5] + - a76 * k[6]), - p, - t + dt)) - copyat_or_push!(k, 8, - f( - uprev + - dt * - (a81 * k[1] + a83 * k[3] + a84 * k[4] + a85 * k[5] + a86 * k[6] + - a87 * k[7]), - p, - t + dt)) - end - if (allow_calc_end && length(k) < 11) || force_calc_end # Have not added the extra stages yet - @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache - copyat_or_push!(k, 9, - f( - uprev + - dt * - (a91 * k[1] + a92 * k[2] + a93 * k[3] + a94 * k[4] + a95 * k[5] + - a96 * k[6] + a97 * k[7] + a98 * k[8]), - p, - t + c6 * dt)) - copyat_or_push!(k, 10, - f( - uprev + - dt * (a101 * k[1] + a102 * k[2] + a103 * k[3] + a104 * k[4] + - a105 * k[5] + a106 * k[6] + a107 * k[7] + a108 * k[8] + - a109 * k[9]), - p, - t + c7 * dt)) - copyat_or_push!(k, 11, - f( - uprev + - dt * (a111 * k[1] + a112 * k[2] + a113 * k[3] + a114 * k[4] + - a115 * k[5] + a116 * k[6] + a117 * k[7] + a118 * k[8] + - a119 * k[9] + a1110 * k[10]), - p, - t + c8 * dt)) - end - nothing -end - -#= -""" -An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine - Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 - -Called to add the extra k9, k10, k11 steps for the Order 5 interpolation when needed -""" -@muladd function _ode_addsteps!(k,t,uprev,u,dt,f,p,cache::BS5Cache,always_calc_begin = false,allow_calc_end = true,force_calc_end = false) - if length(k) < 8 || always_calc_begin - uidx = eachindex(uprev) - @unpack k1,k2,k3,k4,k5,k6,k7,k8,tmp = cache - @unpack c1,c2,c3,c4,c5,a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87 = cache.tab - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*a21*k1[i] - end - f(k2,tmp,p,t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3,tmp,p,t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) - end - f(k4,tmp,p,t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5,tmp,p,t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6,tmp,p,t+c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) - end - f(k7,tmp,p,t+dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) - end - f(k8,tmp,p,t+dt) - copyat_or_push!(k,1,k1) - copyat_or_push!(k,2,k2) - copyat_or_push!(k,3,k3) - copyat_or_push!(k,4,k4) - copyat_or_push!(k,5,k5) - copyat_or_push!(k,6,k6) - copyat_or_push!(k,7,k7) - copyat_or_push!(k,8,k8) - end - if (allow_calc_end && length(k)< 11) || force_calc_end # Have not added the extra stages yet - uidx = eachindex(uprev) - rtmp = similar(cache.k1) - @unpack tmp = cache - @unpack c6,c7,c8,a91,a92,a93,a94,a95,a96,a97,a98,a101,a102,a103,a104,a105,a106,a107,a108,a109,a111,a112,a113,a114,a115,a116,a117,a118,a119,a1110 = cache.tab - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a91*k[1][i]+a92*k[2][i]+a93*k[3][i]+a94*k[4][i]+a95*k[5][i]+a96*k[6][i]+a97*k[7][i]+a98*k[8][i]) - end - f(rtmp,tmp,p,t+c6*dt); copyat_or_push!(k,9,rtmp) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a101*k[1][i]+a102*k[2][i]+a103*k[3][i]+a104*k[4][i]+a105*k[5][i]+a106*k[6][i]+a107*k[7][i]+a108*k[8][i]+a109*k[9][i]) - end - f(rtmp,tmp,p,t+c7*dt); copyat_or_push!(k,10,rtmp) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a111*k[1][i]+a112*k[2][i]+a113*k[3][i]+a114*k[4][i]+a115*k[5][i]+a116*k[6][i]+a117*k[7][i]+a118*k[8][i]+a119*k[9][i]+a1110*k[10][i]) - end - f(rtmp,tmp,p,t+c8*dt); copyat_or_push!(k,11,rtmp) - end - nothing -end -=# diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_caches.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_caches.jl deleted file mode 100644 index 2ac937b058..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_caches.jl +++ /dev/null @@ -1,1561 +0,0 @@ -@cache struct EulerCache{uType, rateType} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - k::rateType - fsalfirst::rateType -end - -@cache struct SplitEulerCache{uType, rateType} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - k::rateType - fsalfirst::rateType -end - -function alg_cache(alg::SplitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - SplitEulerCache(u, uprev, zero(u), zero(rate_prototype), zero(rate_prototype)) -end - -struct SplitEulerConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::SplitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - SplitEulerConstantCache() -end - -function alg_cache(alg::Euler, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - EulerCache(u, uprev, zero(u), zero(rate_prototype), zero(rate_prototype)) -end - -struct EulerConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::Euler, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - EulerConstantCache() -end - -@cache struct HeunCache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - atmp::uNoUnitsType - k::rateType - fsalfirst::rateType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -@cache struct RalstonCache{ - uType, - rateType, - uNoUnitsType, - StageLimiter, - StepLimiter, - Thread -} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - atmp::uNoUnitsType - k::rateType - fsalfirst::rateType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::Heun, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - HeunCache(u, uprev, zero(u), atmp, zero(rate_prototype), - zero(rate_prototype), alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::Ralston, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - RalstonCache(u, uprev, zero(u), atmp, zero(rate_prototype), - zero(rate_prototype), alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -struct HeunConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::Heun, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - HeunConstantCache() -end - -struct RalstonConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::Ralston, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - RalstonConstantCache() -end - -@cache struct MidpointCache{ - uType, - rateType, - uNoUnitsType, - StageLimiter, - StepLimiter, - Thread -} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k::rateType - tmp::uType - atmp::uNoUnitsType - fsalfirst::rateType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -struct MidpointConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::Midpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - k = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - MidpointCache(u, uprev, k, tmp, atmp, fsalfirst, alg.stage_limiter!, alg.step_limiter!, - alg.thread) -end - -function alg_cache(alg::Midpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - MidpointConstantCache() -end - -@cache struct RK4Cache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - fsalfirst::rateType - k₂::rateType - k₃::rateType - k₄::rateType - k::rateType - tmp::uType - atmp::uNoUnitsType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -struct RK4ConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::RK4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k₁ = zero(rate_prototype) - k₂ = zero(rate_prototype) - k₃ = zero(rate_prototype) - k₄ = zero(rate_prototype) - k = zero(rate_prototype) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - RK4Cache(u, uprev, k₁, k₂, k₃, k₄, k, tmp, atmp, alg.stage_limiter!, alg.step_limiter!, - alg.thread) -end - -function alg_cache(alg::RK4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - RK4ConstantCache() -end - -@cache struct BS3Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, - Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - fsalfirst::rateType - k2::rateType - k3::rateType - k4::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::BS3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = BS3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - BS3Cache(u, uprev, k1, k2, k3, k4, utilde, tmp, atmp, tab, alg.stage_limiter!, - alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::BS3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - BS3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct OwrenZen3Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, - StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::OwrenZen3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = OwrenZen3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - OwrenZen3Cache(u, uprev, k1, k2, k3, k4, utilde, tmp, atmp, tab, alg.stage_limiter!, - alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::OwrenZen3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - OwrenZen3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct OwrenZen4Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, - StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::OwrenZen4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = OwrenZen4ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - OwrenZen4Cache(u, uprev, k1, k2, k3, k4, k5, k6, utilde, tmp, atmp, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::OwrenZen4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - OwrenZen4ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct OwrenZen5Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, - StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::OwrenZen5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = OwrenZen5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - OwrenZen5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::OwrenZen5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - OwrenZen5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct BS5Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, - Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::BS5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = BS5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - BS5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -function alg_cache(alg::BS5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - BS5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct Tsit5Cache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, - Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end -if isdefined(Base, :Experimental) && isdefined(Base.Experimental, :silence!) - Base.Experimental.silence!(Tsit5Cache) -end - -function alg_cache(alg::Tsit5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - Tsit5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -TruncatedStacktraces.@truncate_stacktrace Tsit5Cache 1 - -function alg_cache(alg::Tsit5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - Tsit5ConstantCache() -end - -@cache struct DP5Cache{uType, rateType, uNoUnitsType, StageLimiter, StepLimiter, - Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - dense_tmp3::rateType - dense_tmp4::rateType - update::rateType - bspl::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::DP5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = k2 - k7 = zero(rate_prototype) # This is FSAL'd to k1 - dense_tmp3 = k2 - dense_tmp4 = k5 - bspl = k3 - - tmp = zero(u) # has to be separate for FSAL - utilde = tmp - - if eltype(u) != uEltypeNoUnits || calck - update = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - else - update = k7 - atmp = k3 - end - - cache = DP5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, dense_tmp3, dense_tmp4, update, - bspl, utilde, tmp, atmp, alg.stage_limiter!, alg.step_limiter!, - alg.thread) - cache -end - -function alg_cache(alg::DP5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - DP5ConstantCache() -end - -@cache struct Anas5Cache{ - uType, - rateType, - uNoUnitsType, - TabType, - StageLimiter, - StepLimiter, - Thread -} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::Anas5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Anas5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - Anas5Cache(u, - uprev, - k1, - k2, - k3, - k4, - k5, - k6, - k7, - utilde, - tmp, - atmp, - tab, - alg.stage_limiter!, - alg.step_limiter!, - alg.thread) -end - -function alg_cache(alg::Anas5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - Anas5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -@cache struct RKO65Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - tmp::uType - fsalfirst::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -u_cache(c::RKO65Cache) = () -du_cache(c::RKO65Cache) = (c.k, c.du, c.fsalfirst) - -struct RKO65ConstantCache{T1, T2} <: OrdinaryDiffEqConstantCache - α21::T1 - α31::T1 - α41::T1 - α51::T1 - - α32::T1 - α42::T1 - α52::T1 - α62::T1 - - α43::T1 - α53::T1 - α63::T1 - - α54::T1 - α64::T1 - - α65::T1 - - β2::T1 - β3::T1 - β4::T1 - β5::T1 - β6::T1 - - c1::T2 - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - - function RKO65ConstantCache(T1, T2) - # elements of Butcher Table - α21 = T1(1 // 6) - α31 = T1(-15 // 8) - α41 = T1(-9 // 1) - α51 = T1(-3 // 1) - - α32 = T1(21 // 8) - α42 = T1(75 // 7) - α52 = T1(34257 // 8750) - α62 = T1(123 // 380) - - α43 = T1(-5 // 7) - α53 = T1(-114 // 875) - α63 = T1(5 // 2) - - α54 = T1(19 // 1250) - α64 = T1(3 // 20) - - α65 = T1(-75 // 38) - - β2 = T1(54 // 133) - β3 = T1(32 // 21) - β4 = T1(1 // 18) - β5 = T1(-125 // 114) - β6 = T1(1 // 9) - - c1 = T2(2 // 3) - c2 = T2(1 // 6) - c3 = T2(3 // 4) - c4 = T2(1 // 1) - c5 = T2(4 // 5) - c6 = T2(1 // 1) - new{T1, T2}(α21, α31, α41, α51, α32, α42, α52, α62, α43, α53, α63, α54, α64, α65, - β2, β3, β4, β5, β6, c1, c2, c3, c4, c5, c6) - end -end - -function alg_cache(alg::RKO65, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - RKO65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) # why not real(tTypeNoUnits)? -end - -function alg_cache(alg::RKO65, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tmp = zero(u) - - k = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - - fsalfirst = zero(rate_prototype) - - tab = RKO65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - RKO65Cache( - u, uprev, k, k1, k2, k3, k4, k5, k6, tmp, fsalfirst, tab, alg.stage_limiter!, - alg.step_limiter!, alg.thread) -end - -@cache struct FRK65Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, - Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - utilde::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - k9::rateType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -struct FRK65ConstantCache{T1, T2} <: OrdinaryDiffEqConstantCache - α21::T1 - α31::T1 - α41::T1 - α51::T1 - α61::T1 - α71::T1 - α81::T1 - α91::T1 - - α32::T1 - - α43::T1 - α53::T1 - α63::T1 - α73::T1 - α83::T1 - - α54::T1 - α64::T1 - α74::T1 - α84::T1 - α94::T1 - - α65::T1 - α75::T1 - α85::T1 - α95::T1 - - α76::T1 - α86::T1 - α96::T1 - - α87::T1 - α97::T1 - - α98::T1 - - β1::T1 - # β4::T1 - # β5::T1 - # β6::T1 - β7::T1 - β8::T1 - - β1tilde::T1 - β4tilde::T1 - β5tilde::T1 - β6tilde::T1 - β7tilde::T1 - β8tilde::T1 - β9tilde::T1 - - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - c8::T2 - c9::T2 - - d1::T1 - d2::T1 - d3::T1 - d4::T1 - d5::T1 - d6::T1 - d7::T1 - d8::T1 - d9::T1 - d10::T1 - d11::T1 - d12::T1 - d13::T1 - - e1::T1 - e2::T1 - e3::T1 - e4::T1 - e5::T1 - e6::T1 - e7::T1 - e8::T1 - e9::T1 - e10::T1 - e11::T1 - - f1::T1 - f2::T1 - f3::T1 - f4::T1 - f5::T1 - f6::T1 - f7::T1 - f8::T1 - f9::T1 - f10::T1 - f11::T1 - - function FRK65ConstantCache(T1, T2) - - # elements of Butcher Table - α21 = T1(1 // 89) - α31 = T1(-38624 // 142129) - α41 = T1(51 // 1508) - α51 = T1(3259284578 // 3517556363) - α61 = T1(-108363632681 // 45875676369) - α71 = T1(7137368591 // 11299833148) - α81 = T1(8898824396 // 9828950919) - α91 = T1(1026331676 // 33222204855) - - α32 = T1(51442 // 142129) - - α43 = T1(153 // 1508) - α53 = T1(-69727055112 // 19553806387) - α63 = T1(80902506271 // 8700424616) - α73 = T1(-33088067061 // 10572251159) - α83 = T1(25673454973 // 11497947835) - - α54 = T1(36230363390 // 11788838981) - α64 = T1(-120088218786 // 17139312481) - α74 = T1(11481363823 // 3650030081) - α84 = T1(-74239028301 // 15737704666) - α94 = T1(1450675392 // 5936579813) - - α65 = T1(4533285649 // 6676940598) - α75 = T1(-4096673444 // 7349814937) - α85 = T1(222688842816 // 44196813415) - α95 = T1(4617877550 // 16762182457) - - α76 = T1(9911918171 // 12847192605) - α86 = T1(-105204445705 // 30575217706) - α96 = T1(1144867463 // 6520294355) - - α87 = T1(8799291910 // 8966990271) - α97 = T1(1822809703 // 7599996644) - - α98 = T1(79524953 // 2351253316) - - β1 = T1(1026331676 // 33222204855) - #β4 = T1(1450675392//5936579813) - #β5 = T1(4617877550//16762182457) - #β6 = T1(1144867463//6520294355) - β7 = T1(1822809703 // 7599996644) - β8 = T1(79524953 // 2351253316) - - β1tilde = T1(413034411 // 13925408836) - β4tilde = T1(1865954212 // 7538591735) - β5tilde = T1(4451980162 // 16576017119) - β6tilde = T1(1157843020 // 6320223511) - β7tilde = T1(802708729 // 3404369569) - β8tilde = T1(-251398161 // 17050111121) - β9tilde = T1(1 // 20) - - c2 = T2(1 // 89) - c3 = T2(34 // 377) - c4 = T2(51 // 377) - c5 = T2(14497158 // 33407747) - c6 = T2(9744566553 // 16002998914) - c7 = T2(330 // 383) - c8 = T2(1 // 1) - c9 = T2(1 // 1) - - d1 = T1(140209127 // 573775965) - d2 = T1(-8530039 // 263747097) - d3 = T1(-308551 // 104235790) - d4 = T1(233511 // 333733259) - d5 = T1(9126 // 184950985) - d6 = T1(22 // 50434083) - d7 = T1(19 // 424427471) - d8 = T1(-28711 // 583216934059) - d9 = T1(-3831531 // 316297807) - d10 = T1(551767 // 187698280) - d11 = T1(9205 // 210998423) - d12 = T1(-250 // 519462673) - d13 = T1(67 // 327513887) - - e1 = T1(437217689 // 1587032700) - e2 = T1(-15824413 // 592362279) - e3 = T1(-1563775 // 341846569) - e4 = T1(270497 // 369611210) - e5 = T1(-26623 // 453099487) - e6 = T1(-616297487849) - e7 = T1(-47682337 // 491732789) - e8 = T1(-4778275 // 287766311) - e9 = T1(641177 // 265376522) - e10 = T1(44633 // 291742143) - e11 = T1(611 // 223639880) - - f1 = T1(44861261 // 255495624) - f2 = T1(-11270940 // 352635157) - f3 = T1(-182222 // 232874507) - f4 = T1(164263 // 307215200) - f5 = T1(32184 // 652060417) - f6 = T1(-352 // 171021903) - f7 = T1(-18395427 // 101056291) - f8 = T1(-621686 // 139501937) - f9 = T1(2030024 // 612171255) - f10 = T1(-711049 // 7105160932) - f11 = T1(267 // 333462710) - - new{T1, T2}(α21, α31, α41, α51, α61, α71, α81, α91, α32, α43, α53, α63, α73, α83, - α54, α64, α74, α84, α94, α65, α75, α85, α95, α76, α86, α96, α87, α97, - α98, β1, β7, β8, β1tilde, β4tilde, β5tilde, β6tilde, β7tilde, β8tilde, - β9tilde, c2, c3, c4, c5, c6, c7, c8, c9, d1, d2, d3, d4, d5, d6, d7, d8, - d9, d10, d11, d12, d13, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, - f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) - end -end - -function alg_cache(alg::FRK65, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - FRK65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::FRK65, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = FRK65ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - k9 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - FRK65Cache(u, uprev, utilde, k1, k2, k3, k4, k5, k6, k7, k8, k9, tmp, atmp, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -@cache struct RKMCache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - tmp::uType - fsalfirst::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -struct RKMConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - α2::T - α3::T - α4::T - α5::T - α6::T - β1::T - β2::T - β3::T - β4::T - β6::T - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - - function RKMConstantCache(::Type{T}, ::Type{T2}) where {T, T2} - # α2 = T(0.16791846623918) - # α3 = T(0.48298439719700) - # α4 = T(0.70546072965982) - # α5 = T(0.09295870406537) - # α6 = T(0.76210081248836) - # β1 = T(-0.15108370762927) - # β2 = T(0.75384683913851) - # β3 = T(-0.36016595357907) - # β4 = T(0.52696773139913) - # β6 = T(0.23043509067071) - # c2 = T2(0.16791846623918) - # c3 = T2(0.48298439719700) - # c4 = T2(0.70546072965982) - # c5 = T2(0.09295870406537) - # c6 = T2(0.76210081248836) - - α2 = T(0.167266187050662) - α3 = T(0.484574582244783) - α4 = T(0.536909403373491) - α5 = T(0.082069535961948) - α6 = T(0.853923000035347) - β1 = T(-0.028289441132839) - β2 = T(0.463968918564710) - β3 = T(-0.434414348751899) - β4 = T(0.693796229087598) - β6 = T(0.304938642232430) - c2 = T2(0.167266187050662) - c3 = T2(0.484574582244783) - c4 = T2(0.536909403373491) - c5 = T2(0.082069535961948) - c6 = T2(0.853923000035347) - - new{T, T2}(α2, α3, α4, α5, α6, β1, β2, β3, β4, β6, c2, c3, c4, c5, c6) - end -end - -function alg_cache(alg::RKM, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - RKMConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::RKM, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = RKMConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - k = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - tmp = zero(u) - fsalfirst = zero(rate_prototype) - RKMCache(u, uprev, k, k1, k2, k3, k4, k5, k6, tmp, fsalfirst, tab, alg.stage_limiter!, - alg.step_limiter!, alg.thread) -end - -@cache struct MSRK5Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - fsalfirst::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - k9::rateType - k::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::MSRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return MSRK5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::MSRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - k9 = zero(rate_prototype) - k = zero(rate_prototype) - tmp = zero(u) - fsalfirst = zero(u) - tab = MSRK5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - MSRK5Cache(u, uprev, tmp, fsalfirst, k1, k2, k3, k4, k5, k6, k7, k8, k9, k, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -@cache struct MSRK6Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - fsalfirst::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - k9::rateType - k::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::MSRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return MSRK6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::MSRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - k9 = zero(rate_prototype) - k = zero(rate_prototype) - tmp = zero(u) - fsalfirst = zero(u) - tab = MSRK6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - MSRK6Cache(u, uprev, tmp, fsalfirst, k1, k2, k3, k4, k5, k6, k7, k8, k9, k, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -@cache struct PSRK4p7q6Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - tmp::uType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::PSRK4p7q6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return PSRK4p7q6ConstantCache( - constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::PSRK4p7q6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - tmp = zero(u) - tab = PSRK4p7q6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - PSRK4p7q6Cache(u, uprev, k1, k2, k3, k4, k5, k6, tmp, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -@cache struct PSRK3p6q5Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - tmp::uType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::PSRK3p6q5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return PSRK3p6q5ConstantCache( - constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::PSRK3p6q5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - tmp = zero(u) - tab = PSRK3p6q5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - PSRK3p6q5Cache(u, uprev, tmp, k1, k2, k3, k4, k5, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -@cache struct PSRK3p5q4Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - tmp::uType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::PSRK3p5q4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return PSRK3p5q4ConstantCache( - constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::PSRK3p5q4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - tmp = zero(u) - tab = PSRK3p5q4ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - PSRK3p5q4Cache(u, uprev, tmp, k1, k2, k3, k4, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -@cache struct Stepanov5Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::uType - fsalfirst::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k::rateType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::Stepanov5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return Stepanov5ConstantCache(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::Stepanov5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k = zero(rate_prototype) - tmp = zero(u) - fsalfirst = zero(u) - tab = Stepanov5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - Stepanov5Cache(u, - uprev, - tmp, - fsalfirst, - k1, - k2, - k3, - k4, - k5, - k6, - k7, - k, - tab, - alg.stage_limiter!, - alg.step_limiter!, - alg.thread) -end - -@cache struct SIR54Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, StepLimiter, - Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - utilde::uType - tmp::uType - atmp::uNoUnitsType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::SIR54, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return SIR54ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::SIR54, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - utilde = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tmp = zero(u) - tab = SIR54ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - SIR54Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, tab, - alg.stage_limiter!, alg.step_limiter!, alg.thread) -end - -@cache struct Alshina2Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, - StepLimiter, Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - utilde::uType - k1::rateType - k2::rateType - atmp::uNoUnitsType - tmp::uType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::Alshina2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return Alshina2ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::Alshina2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - utilde = zero(u) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tab = Alshina2ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - Alshina2Cache(u, uprev, utilde, k1, k2, atmp, tmp, tab, alg.stage_limiter!, - alg.step_limiter!, alg.thread) -end - -@cache struct Alshina3Cache{uType, rateType, uNoUnitsType, TabType, StageLimiter, - StepLimiter, Thread} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - utilde::uType - k1::rateType - k2::rateType - k3::rateType - atmp::uNoUnitsType - tmp::uType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::Alshina3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return Alshina3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::Alshina3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - utilde = zero(u) - tmp = zero(u) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - tab = Alshina3ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - Alshina3Cache(u, uprev, utilde, k1, k2, k3, atmp, tmp, tab, alg.stage_limiter!, - alg.step_limiter!, alg.thread) -end - -@cache struct Alshina6Cache{uType, rateType, TabType, StageLimiter, StepLimiter, Thread} <: - OrdinaryDiffEqMutableCache - u::uType - uprev::uType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - tmp::uType - tab::TabType - stage_limiter!::StageLimiter - step_limiter!::StepLimiter - thread::Thread -end - -function alg_cache(alg::Alshina6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - return Alshina6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) -end - -function alg_cache(alg::Alshina6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - tmp = zero(u) - tab = Alshina6ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - Alshina6Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, tmp, tab, alg.stage_limiter!, - alg.step_limiter!, alg.thread) -end - -@cache struct FunctionMapCache{uType, rateType} <: OrdinaryDiffEqMutableCache - u::uType - uprev::uType - tmp::rateType -end - -function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - FunctionMapCache(u, uprev, - FunctionMap_scale_by_time(alg) ? rate_prototype : - (eltype(u) <: Enum ? copy(u) : zero(u))) -end - -struct FunctionMapConstantCache <: OrdinaryDiffEqConstantCache end - -function alg_cache(alg::FunctionMap, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - FunctionMapConstantCache() -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_perform_step.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_perform_step.jl deleted file mode 100644 index 1cd465607d..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_perform_step.jl +++ /dev/null @@ -1,2326 +0,0 @@ -function initialize!(integrator, cache::BS3ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::BS3ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4 = cache - k1 = integrator.fsalfirst - a1 = dt * a21 - k2 = f(uprev + a1 * k1, p, t + c1 * dt) - a2 = dt * a32 - k3 = f(uprev + a2 * k2, p, t + c2 * dt) - u = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(u, p, t + dt) - integrator.fsallast = k4 - integrator.stats.nf += 3 - if integrator.opts.adaptive - utilde = dt * (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::BS3Cache) - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.fsalfirst = cache.fsalfirst # done by pointers, no copying - integrator.fsallast = cache.k4 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::BS3Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack k2, k3, k4, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4 = cache.tab - # k1 = cache.fsalfirst - k1 = integrator.fsalfirst - a1 = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a1 * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - a2 = dt * a32 - @.. broadcast=false thread=thread tmp=uprev + a2 * k2 - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread u=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k4, u, p, t + dt) - integrator.stats.nf += 3 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde2 * k2 + - btilde3 * k3 + btilde4 * k4) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end -end - -function initialize!(integrator, cache::OwrenZen3ConstantCache) - integrator.kshortsize = 4 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::OwrenZen3ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3 = cache - k1 = integrator.fsalfirst - a1 = dt * a21 - k2 = f(uprev + a1 * k1, p, t + c1 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c2 * dt) - u = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(u, p, t + dt) - integrator.fsallast = k4 - integrator.stats.nf += 3 - if integrator.opts.adaptive - utilde = dt * (btilde1 * k1 + btilde2 * k2 + btilde3 * k3) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.u = u -end - -function initialize!(integrator, cache::OwrenZen3Cache) - integrator.kshortsize = 4 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k4 # setup pointers - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::OwrenZen3Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack k1, k2, k3, k4, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3 = cache.tab - a1 = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a1 * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread u=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k4, u, p, t + dt) - integrator.stats.nf += 3 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde2 * k2 + - btilde3 * k3) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end -end - -function initialize!(integrator, cache::OwrenZen4ConstantCache) - integrator.kshortsize = 6 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::OwrenZen4ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, btilde5 = cache - k1 = integrator.fsalfirst - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - u = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(u, p, t + dt) - integrator.fsallast = k6 - integrator.stats.nf += 5 - if integrator.opts.adaptive - utilde = dt * (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.u = u -end - -function initialize!(integrator, cache::OwrenZen4Cache) - integrator.kshortsize = 6 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k6 # setup pointers - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::OwrenZen4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack k1, k2, k3, k4, k5, k6, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, btilde5 = cache.tab - a = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k6, u, p, t + dt) - integrator.stats.nf += 5 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + - btilde4 * k4 + - btilde5 * k5) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - return nothing -end - -#= -@muladd function perform_step!(integrator, cache::OwrenZen4Cache, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - uidx = eachindex(integrator.uprev) - @unpack k1,k2,k3,k4,k5,k6,utilde,tmp,atmp = cache - @unpack a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a63,a64,a65,c1,c2,c3,c4,btilde1,btilde3,btilde4,btilde5 = cache.tab - a = dt*a21 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2, tmp, p, t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3, tmp, p, t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) - end - f(k4, tmp, p, t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5, tmp, p, t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds u[i] = uprev[i]+dt*(a61*k1[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6, u, p, t+dt) - integrator.stats.nf += 5 - if integrator.opts.adaptive - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i]) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - integrator.EEst = integrator.opts.internalnorm(atmp,t) - end -end -=# - -function initialize!(integrator, cache::OwrenZen5ConstantCache) - integrator.kshortsize = 8 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::OwrenZen5ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache - k1 = integrator.fsalfirst - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, - t + c5 * dt) - k7 = f(uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), - p, t + c6 * dt) - u = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) - k8 = f(u, p, t + dt) - integrator.fsallast = k8 - integrator.stats.nf += 7 - if integrator.opts.adaptive - utilde = dt * - (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.k[8] = k8 - integrator.u = u -end - -function initialize!(integrator, cache::OwrenZen5Cache) - integrator.kshortsize = 8 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.k[8] = cache.k8 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k8 # setup pointers - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::OwrenZen5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - a = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + k3) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k6, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + - a75 * k5 + - a76 * k6) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k7, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + - a86 * k6 + a87 * k7) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k8, u, p, t + dt) - integrator.stats.nf += 7 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + - btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - return nothing -end - -#= -@muladd function perform_step!(integrator, cache::OwrenZen5Cache, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - uidx = eachindex(integrator.uprev) - @unpack k1,k2,k3,k4,k5,k6,k7,k8,utilde,tmp,atmp = cache - @unpack a21,a31,a32,a41,a42,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,c1,c2,c3,c4,c5,c6,btilde1,btilde3,btilde4,btilde5,btilde6,btilde7 = cache.tab - a = dt*a21 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2, tmp, p, t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3, tmp, p, t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+k3[i]) - end - f(k4, tmp, p, t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5, tmp, p, t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6, tmp, p, t+c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) - end - f(k7, tmp, p, t+c6*dt) - @tight_loop_macros for i in uidx - @inbounds u[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) - end - f(k8, u, p, t+dt) - integrator.stats.nf += 7 - if integrator.opts.adaptive - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i] + btilde6*k6[i] + btilde7*k7[i]) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - integrator.EEst = integrator.opts.internalnorm(atmp,t) - end -end -=# - -function initialize!(integrator, cache::BS5ConstantCache) - alg = unwrap_alg(integrator, false) - alg.lazy ? (integrator.kshortsize = 8) : (integrator.kshortsize = 11) - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:7 - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast - - if !alg.lazy - @inbounds for i in 9:11 - integrator.k[i] = zero(integrator.fsalfirst) - end - end -end - -@muladd function perform_step!(integrator, cache::BS5ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache - k1 = integrator.fsalfirst - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - k6 = f(uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5), p, - t + c5 * dt) - k7 = f(uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6), - p, t + dt) - integrator.stats.nf += 6 - u = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) - integrator.fsallast = f(u, p, t + dt) - k8 = integrator.fsallast - integrator.stats.nf += 1 - if integrator.opts.adaptive - uhat = dt * (bhat1 * k1 + bhat3 * k3 + bhat4 * k4 + bhat5 * k5 + bhat6 * k6) - utilde = dt * - (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + - btilde7 * k7 + btilde8 * k8) - atmp = calculate_residuals(uhat, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - EEst1 = integrator.opts.internalnorm(atmp, t) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - EEst2 = integrator.opts.internalnorm(atmp, t) - integrator.EEst = max(EEst1, EEst2) - end - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.k[8] = k8 - integrator.u = u - - alg = unwrap_alg(integrator, false) - if !alg.lazy && (integrator.opts.adaptive == false || - accept_step_controller(integrator, integrator.opts.controller)) - @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache - k = integrator.k - k[9] = f( - uprev + - dt * (a91 * k[1] + a92 * k[2] + a93 * k[3] + a94 * k[4] + a95 * k[5] + - a96 * k[6] + a97 * k[7] + a98 * k[8]), - p, - t + c6 * dt) - k[10] = f( - uprev + - dt * - (a101 * k[1] + a102 * k[2] + a103 * k[3] + a104 * k[4] + a105 * k[5] + - a106 * k[6] + a107 * k[7] + a108 * k[8] + a109 * k[9]), - p, - t + c7 * dt) - k[11] = f( - uprev + - dt * - (a111 * k[1] + a112 * k[2] + a113 * k[3] + a114 * k[4] + a115 * k[5] + - a116 * k[6] + a117 * k[7] + a118 * k[8] + a119 * k[9] + a1110 * k[10]), - p, t + c8 * dt) - integrator.stats.nf += 3 - end -end - -function initialize!(integrator, cache::BS5Cache) - alg = unwrap_alg(integrator, false) - alg.lazy ? (integrator.kshortsize = 8) : (integrator.kshortsize = 11) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.k[8] = cache.k8 - - if !alg.lazy - integrator.k[9] = similar(cache.k1) - integrator.k[10] = similar(cache.k1) - integrator.k[11] = similar(cache.k1) - end - - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k8 # setup pointers - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::BS5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab - a = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k6, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + - a75 * k5 + - a76 * k6) - stage_limiter!(tmp, integrator, p, t + dt) - f(k7, tmp, p, t + dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + - a86 * k6 + a87 * k7) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k8, u, p, t + dt) - integrator.stats.nf += 7 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * - (bhat1 * k1 + bhat3 * k3 + bhat4 * k4 + - bhat5 * k5 + - bhat6 * k6) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - EEst1 = integrator.opts.internalnorm(atmp, t) - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + - btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + - btilde7 * k7 + - btilde8 * k8) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - EEst2 = integrator.opts.internalnorm(atmp, t) - integrator.EEst = max(EEst1, EEst2) - end - alg = unwrap_alg(integrator, false) - if !alg.lazy && (integrator.opts.adaptive == false || - accept_step_controller(integrator, integrator.opts.controller)) - k = integrator.k - @unpack c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = cache.tab - @.. broadcast=false thread=thread tmp=uprev + - dt * (a91 * k[1] + a92 * k[2] + a93 * k[3] + - a94 * k[4] + - a95 * k[5] + a96 * k[6] + a97 * k[7] + - a98 * k[8]) - f(k[9], tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * - (a101 * k[1] + a102 * k[2] + a103 * k[3] + - a104 * k[4] + - a105 * k[5] + a106 * k[6] + a107 * k[7] + - a108 * k[8] + - a109 * k[9]) - f(k[10], tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * - (a111 * k[1] + a112 * k[2] + a113 * k[3] + - a114 * k[4] + - a115 * k[5] + a116 * k[6] + a117 * k[7] + - a118 * k[8] + - a119 * k[9] + a1110 * k[10]) - f(k[11], tmp, p, t + c8 * dt) - integrator.stats.nf += 3 - end - return nothing -end - -#= -@muladd function perform_step!(integrator, cache::BS5Cache, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - uidx = eachindex(integrator.uprev) - @unpack k1,k2,k3,k4,k5,k6,k7,k8,utilde,tmp,atmp = cache - @unpack c1,c2,c3,c4,c5,a21,a31,a32,a41,a42,a43,a51,a52,a53,a54,a61,a62,a63,a64,a65,a71,a72,a73,a74,a75,a76,a81,a83,a84,a85,a86,a87,bhat1,bhat3,bhat4,bhat5,bhat6,btilde1,btilde3,btilde4,btilde5,btilde6,btilde7,btilde8 = cache.tab - a = dt*a21 - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+a*k1[i] - end - f(k2, tmp, p, t+c1*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a31*k1[i]+a32*k2[i]) - end - f(k3, tmp, p, t+c2*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a41*k1[i]+a42*k2[i]+a43*k3[i]) - end - f(k4, tmp, p, t+c3*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a51*k1[i]+a52*k2[i]+a53*k3[i]+a54*k4[i]) - end - f(k5, tmp, p, t+c4*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a61*k1[i]+a62*k2[i]+a63*k3[i]+a64*k4[i]+a65*k5[i]) - end - f(k6, tmp, p, t+c5*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a71*k1[i]+a72*k2[i]+a73*k3[i]+a74*k4[i]+a75*k5[i]+a76*k6[i]) - end - f(k7, tmp, p, t+dt) - @tight_loop_macros for i in uidx - @inbounds u[i] = uprev[i]+dt*(a81*k1[i]+a83*k3[i]+a84*k4[i]+a85*k5[i]+a86*k6[i]+a87*k7[i]) - end - f(k8, u, p, t+dt) - integrator.stats.nf += 7 - if integrator.opts.adaptive - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(bhat1*k1[i] + bhat3*k3[i] + bhat4*k4[i] + bhat5*k5[i] + bhat6*k6[i]) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - EEst1 = integrator.opts.internalnorm(atmp,t) - @tight_loop_macros for i in uidx - @inbounds utilde[i] = dt*(btilde1*k1[i] + btilde3*k3[i] + btilde4*k4[i] + btilde5*k5[i] + btilde6*k6[i] + btilde7*k7[i] + btilde8*k8[i]) - end - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol,integrator.opts.internalnorm,t) - EEst2 = integrator.opts.internalnorm(atmp,t) - integrator.EEst = max(EEst1,EEst2) - end - - alg = unwrap_alg(integrator, false) - if !alg.lazy && (integrator.opts.adaptive == false || accept_step_controller(integrator, integrator.opts.controller)) - k = integrator.k - @unpack c6,c7,c8,a91,a92,a93,a94,a95,a96,a97,a98,a101,a102,a103,a104,a105,a106,a107,a108,a109,a111,a112,a113,a114,a115,a116,a117,a118,a119,a1110 = cache.tab - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a91*k[1][i]+a92*k[2][i]+a93*k[3][i]+a94*k[4][i]+a95*k[5][i]+a96*k[6][i]+a97*k[7][i]+a98*k[8][i]) - end - f(k[9],tmp,p,t+c6*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a101*k[1][i]+a102*k[2][i]+a103*k[3][i]+a104*k[4][i]+a105*k[5][i]+a106*k[6][i]+a107*k[7][i]+a108*k[8][i]+a109*k[9][i]) - end - f(k[10],tmp,p,t+c7*dt) - @tight_loop_macros for i in uidx - @inbounds tmp[i] = uprev[i]+dt*(a111*k[1][i]+a112*k[2][i]+a113*k[3][i]+a114*k[4][i]+a115*k[5][i]+a116*k[6][i]+a117*k[7][i]+a118*k[8][i]+a119*k[9][i]+a1110*k[10][i]) - end - f(k[11],tmp,p,t+c8*dt) - integrator.stats.nf += 3 - end -end -=# - -function initialize!(integrator, cache::Tsit5ConstantCache) - integrator.kshortsize = 7 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::Tsit5ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 - k1 = integrator.fsalfirst - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - g6 = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(g6, p, t + dt) - u = uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) - integrator.fsallast = f(u, p, t + dt) - k7 = integrator.fsallast - integrator.stats.nf += 6 - if integrator.alg isa CompositeAlgorithm - g7 = u - # Hairer II, page 22 modified to use the Inf norm - integrator.eigen_est = integrator.opts.internalnorm( - maximum(abs.(k7 .- k6) ./ (g7 .- g6)), t) - end - if integrator.opts.adaptive - utilde = dt * - (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + - btilde6 * k6 + btilde7 * k7) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.u = u -end - -function initialize!(integrator, cache::Tsit5Cache) - integrator.kshortsize = 7 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k7 # setup pointers - resize!(integrator.k, integrator.kshortsize) - # Setup k pointers - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - return nothing -end - -@muladd function perform_step!(integrator, cache::Tsit5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract Tsit5ConstantCacheActual T T2 - @unpack k1, k2, k3, k4, k5, k6, k7, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - a = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, f, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, f, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, f, p, t + c3 * dt) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, f, p, t + c4 * dt) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, f, p, t + dt) - f(k6, tmp, p, t + dt) - @.. broadcast=false thread=thread u=uprev + - dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + - a75 * k5 + a76 * k6) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k7, u, p, t + dt) - integrator.stats.nf += 6 - if integrator.alg isa CompositeAlgorithm - g7 = u - g6 = tmp - # Hairer II, page 22 modified to use Inf norm - @.. broadcast=false thread=thread utilde=abs((k7 - k6) / (g7 - g6)) - integrator.eigen_est = integrator.opts.internalnorm(norm(utilde, Inf), t) - end - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde2 * k2 + - btilde3 * k3 + btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - return nothing -end - -function initialize!(integrator, cache::DP5ConstantCache) - integrator.kshortsize = 4 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - @inbounds for i in eachindex(integrator.k) - integrator.k[i] = zero(integrator.fsalfirst) - end -end - -@muladd function perform_step!(integrator, cache::DP5ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract DP5ConstantCacheActual T T2 - k1 = integrator.fsalfirst - a = dt * a21 - k2 = f(uprev + a * k1, p, t + c1 * dt) - k3 = f(uprev + dt * (a31 * k1 + a32 * k2), p, t + c2 * dt) - k4 = f(uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3), p, t + c3 * dt) - k5 = f(uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4), p, t + c4 * dt) - g6 = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(g6, p, t + dt) - update = a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6 - u = uprev + dt * update - integrator.fsallast = f(u, p, t + dt) - k7 = integrator.fsallast - integrator.stats.nf += 6 - if integrator.alg isa CompositeAlgorithm - g7 = u - # Hairer II, page 22 modified to use the Inf norm - integrator.eigen_est = integrator.opts.internalnorm( - maximum(abs.(k7 .- k6) ./ (g7 .- g6)), t) - end - if integrator.opts.adaptive - utilde = dt * - (btilde1 * k1 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.k[1] = update - bspl = k1 - update - integrator.k[2] = bspl - integrator.k[3] = update - k7 - bspl - integrator.k[4] = d1 * k1 + d3 * k3 + d4 * k4 + d5 * k5 + d6 * k6 + d7 * k7 - integrator.u = u -end - -function initialize!(integrator, cache::DP5Cache) - integrator.kshortsize = 4 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.update - integrator.k[2] = cache.bspl - integrator.k[3] = cache.dense_tmp3 - integrator.k[4] = cache.dense_tmp4 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k7 - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::DP5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - T = constvalue(recursive_unitless_bottom_eltype(u)) - T2 = constvalue(typeof(one(t))) - @OnDemandTableauExtract DP5ConstantCacheActual T T2 - @unpack k1, k2, k3, k4, k5, k6, k7, dense_tmp3, dense_tmp4, update, bspl, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - a = dt * a21 - @.. broadcast=false thread=thread tmp=uprev + a * k1 - stage_limiter!(tmp, integrator, p, t + c1 * dt) - f(k2, tmp, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k3, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k4, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k5, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, integrator, p, t + dt) - f(k6, tmp, p, t + dt) - @.. broadcast=false thread=thread update=a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + - a76 * k6 - @.. broadcast=false thread=thread u=uprev + dt * update - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k7, u, p, t + dt) - integrator.stats.nf += 6 - if integrator.alg isa CompositeAlgorithm - g6 = tmp - g7 = u - # Hairer II, page 22 modified to use Inf norm - @.. broadcast=false thread=thread utilde=abs((k7 - k6) / (g7 - g6)) - integrator.eigen_est = integrator.opts.internalnorm( - norm(utilde, Inf) * oneunit(t), t) - end - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (btilde1 * k1 + btilde3 * k3 + - btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - if integrator.opts.calck - #integrator.k[4] == k5 - @.. broadcast=false thread=thread integrator.k[4]=d1 * k1 + d3 * k3 + d4 * k4 + - d5 * k5 + - d6 * k6 + d7 * k7 - #bspl == k3 - @.. broadcast=false thread=thread bspl=k1 - update - # k6 === integrator.k[3] === k2 - @.. broadcast=false thread=thread integrator.k[3]=update - k7 - bspl - end - return nothing -end - -function initialize!(integrator, cache::RKO65ConstantCache) - integrator.kshortsize = 6 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::RKO65ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack α21, α31, α41, α51, α32, α42, α52, α62, α43, α53, α63, α54, α64, α65, β2, β3, β4, β5, β6, c1, c2, c3, c4, c5, c6 = cache - - #k1=integrator.fsalfirst #f(uprev,p,t) - k1 = f(uprev, p, t + c1 * dt) - k2 = f(uprev + α21 * dt * k1, p, t + c2 * dt) - k3 = f(uprev + α31 * dt * k1 + α32 * dt * k2, p, t + c3 * dt) - k4 = f(uprev + α41 * dt * k1 + α42 * dt * k2 + α43 * dt * k3, p, t + c4 * dt) - k5 = f(uprev + α51 * dt * k1 + α52 * dt * k2 + α53 * dt * k3 + α54 * dt * k4, p, - t + c5 * dt) - k6 = f(uprev + α62 * dt * k2 + α63 * dt * k3 + α64 * dt * k4 + α65 * dt * k5, p, - t + c6 * dt) - u = uprev + dt * (β2 * k2 + β3 * k3 + β4 * k4 + β5 * k5 + β6 * k6) - - integrator.fsallast = f(u, p, t + dt) # For interpolation, then FSAL'd - - integrator.stats.nf += 6 - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.u = u -end - -function initialize!(integrator, cache::RKO65Cache) - @unpack k, fsalfirst = cache - integrator.kshortsize = 6 - resize!(integrator.k, integrator.kshortsize) - - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k6 # setup pointers - - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k6 # setup pointers - - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::RKO65Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, k, k1, k2, k3, k4, k5, k6, stage_limiter!, step_limiter!, thread = cache - @unpack α21, α31, α41, α51, α32, α42, α52, α62, α43, α53, α63, α54, α64, α65, β2, β3, β4, β5, β6, c1, c2, c3, c4, c5, c6 = cache.tab - #println("L221: tmp", tmp) - f(k1, uprev, p, t + c1 * dt) - @.. broadcast=false thread=thread tmp=uprev + α21 * dt * k1 - stage_limiter!(tmp, integrator, p, t + c2 * dt) - #println("L224: tmp/k", tmp, k1) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + α31 * dt * k1 + α32 * dt * k2 - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + α41 * dt * k1 + α42 * dt * k2 + - α43 * dt * k3 - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + α51 * dt * k1 + α52 * dt * k2 + - α53 * dt * k3 + - α54 * dt * k4 - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + α62 * dt * k2 + α63 * dt * k3 + - α64 * dt * k4 + - α65 * dt * k5 - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - - @.. broadcast=false thread=thread u=uprev + - dt * - (β2 * k2 + β3 * k3 + β4 * k4 + β5 * k5 + β6 * k6) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - #println("L238: tmp/u", tmp, u) - integrator.stats.nf += 6 - - #return nothing -end - -function initialize!(integrator, cache::FRK65ConstantCache) - integrator.kshortsize = 9 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::FRK65ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack α21, α31, α41, α51, α61, α71, α81, α91, α32, α43, α53, α63, α73, α83, α54, α64, α74, α84, α94, α65, α75, α85, α95, α76, α86, α96, α87, α97, α98, β1, β7, β8, β1tilde, β4tilde, β5tilde, β6tilde, β7tilde, β8tilde, β9tilde, c2, c3, c4, c5, c6, c7, c8, c9, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11 = cache - alg = unwrap_alg(integrator, false) - ν = alg.omega * dt - νsq = ν^2 - β4 = (d1 + νsq * (d2 + νsq * (d3 + νsq * (d4 + νsq * (d5 + νsq * (d6 + +νsq * d7)))))) / - (1 + - νsq * (d8 + νsq * (d9 + νsq * (d10 + νsq * (d11 + νsq * (d12 + +νsq * d13)))))) - β5 = (e1 + νsq * (e2 + νsq * (e3 + νsq * (e4 + νsq * (e5 + νsq * e6))))) / - (1 + νsq * (e8 + νsq * (e9 + νsq * (e10 + νsq * e11)))) - β6 = (f1 + νsq * (f2 + νsq * (f3 + νsq * (f4 + νsq * (f5 + νsq * f6))))) / - (1 + νsq * (f8 + νsq * (f9 + νsq * (f10 + νsq * f11)))) - - k1 = integrator.fsalfirst - k2 = f(uprev + α21 * dt * k1, p, t + c2 * dt) - k3 = f(uprev + α31 * dt * k1 + α32 * dt * k2, p, t + c3 * dt) - k4 = f(uprev + α41 * dt * k1 + α43 * dt * k3, p, t + c4 * dt) - k5 = f(uprev + α51 * dt * k1 + α53 * dt * k3 + α54 * dt * k4, p, t + c5 * dt) - k6 = f(uprev + α61 * dt * k1 + α63 * dt * k3 + α64 * dt * k4 + α65 * dt * k5, p, - t + c6 * dt) - k7 = f( - uprev + α71 * dt * k1 + α73 * dt * k3 + α74 * dt * k4 + α75 * dt * k5 + - α76 * dt * k6, - p, - t + c7 * dt) - k8 = f( - uprev + α81 * dt * k1 + α83 * dt * k3 + α84 * dt * k4 + α85 * dt * k5 + - α86 * dt * k6 + α87 * dt * k7, - p, - t + c8 * dt) - u = uprev + dt * (β1 * k1 + β4 * k4 + β5 * k5 + β6 * k6 + β7 * k7 + β8 * k8) - integrator.fsallast = f(u, p, t + dt) - k9 = integrator.fsallast - if integrator.opts.adaptive - utilde = dt * - (β1tilde * k1 + β4tilde * k4 + β5tilde * k5 + β6tilde * k6 + β7tilde * k7 + - β8tilde * k8 + β9tilde * k9) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.stats.nf += 8 - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.k[8] = k8 - integrator.k[9] = k9 - integrator.u = u -end - -function initialize!(integrator, cache::FRK65Cache) - integrator.kshortsize = 9 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k9 - - resize!(integrator.k, integrator.kshortsize) - - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.k[8] = cache.k8 - integrator.k[9] = cache.k9 - - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::FRK65Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, k1, k2, k3, k4, k5, k6, k7, k8, k9, utilde, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack α21, α31, α41, α51, α61, α71, α81, α91, α32, α43, α53, α63, α73, α83, α54, α64, α74, α84, α94, α65, α75, α85, α95, α76, α86, α96, α87, α97, α98, β1, β7, β8, β1tilde, β4tilde, β5tilde, β6tilde, β7tilde, β8tilde, β9tilde, c2, c3, c4, c5, c6, c7, c8, c9, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11 = cache.tab - alg = unwrap_alg(integrator, false) - - ν = alg.omega * dt - νsq = ν^2 - β4 = (d1 + νsq * (d2 + νsq * (d3 + νsq * (d4 + νsq * (d5 + νsq * (d6 + +νsq * d7)))))) / - (1 + - νsq * (d8 + νsq * (d9 + νsq * (d10 + νsq * (d11 + νsq * (d12 + +νsq * d13)))))) - β5 = (e1 + νsq * (e2 + νsq * (e3 + νsq * (e4 + νsq * (e5 + νsq * e6))))) / - (1 + νsq * (e8 + νsq * (e9 + νsq * (e10 + νsq * e11)))) - β6 = (f1 + νsq * (f2 + νsq * (f3 + νsq * (f4 + νsq * (f5 + νsq * f6))))) / - (1 + νsq * (f8 + νsq * (f9 + νsq * (f10 + νsq * f11)))) - - @.. broadcast=false thread=thread tmp=uprev + α21 * dt * k1 - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + α31 * dt * k1 + α32 * dt * k2 - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + α41 * dt * k1 + α43 * dt * k3 - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + α51 * dt * k1 + α53 * dt * k3 + - α54 * dt * k4 - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + α61 * dt * k1 + α63 * dt * k3 + - α64 * dt * k4 + - α65 * dt * k5 - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + α71 * dt * k1 + α73 * dt * k3 + - α74 * dt * k4 + - α75 * dt * k5 + α76 * dt * k6 - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + α81 * dt * k1 + α83 * dt * k3 + - α84 * dt * k4 + - α85 * dt * k5 + α86 * dt * k6 + α87 * dt * k7 - stage_limiter!(tmp, integrator, p, t + c8 * dt) - f(k8, tmp, p, t + c8 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (β1 * k1 + β4 * k4 + β5 * k5 + β6 * k6 + β7 * k7 + - β8 * k8) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k9, u, p, t + dt) - - integrator.stats.nf += 8 - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (β1tilde * k1 + β4tilde * k4 + - β5tilde * k5 + - β6tilde * k6 + β7tilde * k7 + - β8tilde * k8 + - β9tilde * k9) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - return nothing -end - -function initialize!(integrator, cache::RKMConstantCache) - integrator.kshortsize = 6 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::RKMConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack α2, α3, α4, α5, α6, β1, β2, β3, β4, β6, c2, c3, c4, c5, c6 = cache - - #k1 = f(uprev, p, t) - k1 = integrator.fsalfirst - k2 = f(uprev + α2 * dt * k1, p, t + c2 * dt) - k3 = f(uprev + α3 * dt * k2, p, t + c3 * dt) - k4 = f(uprev + α4 * dt * k3, p, t + c4 * dt) - k5 = f(uprev + α5 * dt * k4, p, t + c5 * dt) - k6 = f(uprev + α6 * dt * k5, p, t + c6 * dt) - u = uprev + dt * (β1 * k1 + β2 * k2 + β3 * k3 + β4 * k4 + β6 * k6) - - integrator.fsallast = f(u, p, t + dt) #interpolation then FSAL'd - integrator.stats.nf += 6 - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - # integrator.k[1] = integrator.fsalfirst - # integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::RKMCache) - @unpack k, fsalfirst = cache - integrator.kshortsize = 6 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - - integrator.fsalfirst = cache.k1 - integrator.fsallast = zero(integrator.fsalfirst) # setup pointers - - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::RKMCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k, k1, k2, k3, k4, k5, k6, stage_limiter!, step_limiter!, thread = cache - @unpack α2, α3, α4, α5, α6, β1, β2, β3, β4, β6, c2, c3, c4, c5, c6 = cache.tab - - @.. broadcast=false thread=thread tmp=uprev + α2 * dt * k1 - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + α3 * dt * k2 - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + α4 * dt * k3 - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + α5 * dt * k4 - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + α6 * dt * k5 - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (β1 * k1 + β2 * k2 + β3 * k3 + β4 * k4 + β6 * k6) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(integrator.fsallast, u, p, t + dt) - integrator.stats.nf += 6 - return nothing -end - -function initialize!(integrator, cache::PSRK4p7q6ConstantCache) - integrator.kshortsize = 6 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = zero(integrator.fsalfirst) - integrator.k[3] = zero(integrator.fsalfirst) - integrator.k[4] = zero(integrator.fsalfirst) - integrator.k[5] = zero(integrator.fsalfirst) - integrator.k[6] = integrator.fsallast -end - -function perform_step!(integrator, cache::PSRK4p7q6ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b2, b3, b4, b5, b6, c2, c3, c4, c5, c6 = cache - - k1 = f(uprev, p, t) - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - k5 = f(tmp, p, t + dt * c5) - tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(tmp, p, t + dt * c6) - u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) - - integrator.stats.nf += 6 - integrator.fsallast = k6 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.u = u -end - -function initialize!(integrator, cache::PSRK4p7q6Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 6 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k6 -end - -function perform_step!(integrator, cache::PSRK4p7q6Cache, repeat_step = false) - @unpack k1, k2, k3, k4, k5, k6, tmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b2, b3, b4, b5, b6, c2, c3, c4, c5, c6 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - f(k1, uprev, p, t) - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + - b6 * k6) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - integrator.stats.nf += 6 - integrator.fsallast = k6 - return nothing -end - -function initialize!(integrator, cache::PSRK3p6q5ConstantCache) - integrator.kshortsize = 5 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = zero(integrator.fsalfirst) - integrator.k[3] = zero(integrator.fsalfirst) - integrator.k[4] = zero(integrator.fsalfirst) - integrator.k[5] = integrator.fsallast -end - -function perform_step!(integrator, cache::PSRK3p6q5ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, b1, b2, b3, b4, b5, c2, c3, c4, c5 = cache - - k1 = f(uprev, p, t) - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - k5 = f(tmp, p, t + dt * c5) - u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5) - - integrator.stats.nf += 5 - integrator.fsallast = k5 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.u = u -end - -function initialize!(integrator, cache::PSRK3p6q5Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 5 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k5 -end - -function perform_step!(integrator, cache::PSRK3p6q5Cache, repeat_step = false) - @unpack k1, k2, k3, k4, k5, tmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, b1, b2, b3, b4, b5, c2, c3, c4, c5 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - f(k1, uprev, p, t) - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - integrator.stats.nf += 5 - integrator.fsallast = k5 - return nothing -end - -function initialize!(integrator, cache::PSRK3p5q4ConstantCache) - integrator.kshortsize = 4 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = zero(integrator.fsalfirst) - integrator.k[3] = zero(integrator.fsalfirst) - integrator.k[4] = integrator.fsallast -end - -function perform_step!(integrator, cache::PSRK3p5q4ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a31, a32, a41, a42, a43, b1, b2, b3, b4, c2, c3, c4 = cache - - k1 = f(uprev, p, t) - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4) - - integrator.fsallast = k4 - integrator.stats.nf += 4 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.u = u -end - -function initialize!(integrator, cache::PSRK3p5q4Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 4 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k4 -end - -function perform_step!(integrator, cache::PSRK3p5q4Cache, repeat_step = false) - @unpack k1, k2, k3, k4, tmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, b1, b2, b3, b4, c2, c3, c4 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - f(k1, uprev, p, t) - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - - integrator.stats.nf += 4 - integrator.fsallast = k4 - return nothing -end - -function initialize!(integrator, cache::MSRK5ConstantCache) - integrator.kshortsize = 9 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.fsallast = zero(integrator.fsalfirst) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -function perform_step!(integrator, cache::MSRK5ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache - - k1 = integrator.fsalfirst - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - tmp = uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) - k5 = f(tmp, p, t + dt * c5) - tmp = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(tmp, p, t + dt * c6) - tmp = uprev + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) - k7 = f(tmp, p, t + dt * c7) - tmp = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) - k8 = f(tmp, p, t + dt * c8) - u = uprev + dt * (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + b8 * k8) - k9 = f(u, p, t + dt) - integrator.fsallast = k9 - integrator.stats.nf += 8 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.k[8] = k8 - integrator.k[9] = k9 - integrator.u = u -end - -function initialize!(integrator, cache::MSRK5Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 9 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.k[8] = cache.k8 - integrator.k[9] = cache.k9 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k9 - - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::MSRK5Cache, repeat_step = false) - @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, tmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + - a76 * k6) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + - a86 * k6 + - a87 * k7) - - stage_limiter!(tmp, integrator, p, t + c8 * dt) - f(k8, tmp, p, t + c8 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + - b8 * k8) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k9, u, p, t + dt) - integrator.stats.nf += 8 - integrator.fsallast = k9 - - return nothing -end - -function initialize!(integrator, cache::MSRK6ConstantCache) - integrator.kshortsize = 9 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.fsallast = zero(integrator.fsalfirst) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -function perform_step!(integrator, cache::MSRK6ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache - - k1 = integrator.fsalfirst - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - tmp = uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) - k5 = f(tmp, p, t + dt * c5) - tmp = uprev + dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(tmp, p, t + dt * c6) - tmp = uprev + dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) - k7 = f(tmp, p, t + dt * c7) - tmp = uprev + dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + a86 * k6 + a87 * k7) - k8 = f(tmp, p, t + dt * c8) - u = uprev + dt * (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + b8 * k8) - k9 = f(u, p, t + dt) - integrator.fsallast = k9 - integrator.stats.nf += 8 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.k[8] = k8 - integrator.k[9] = k9 - integrator.u = u -end - -function initialize!(integrator, cache::MSRK6Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 9 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.k[8] = cache.k8 - integrator.k[9] = cache.k9 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k9 - - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::MSRK6Cache, repeat_step = false) - @unpack k1, k2, k3, k4, k5, k6, k7, k8, k9, tmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, c3, c4, c5, c6, c7, c8 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a51 * k1 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a63 * k3 + a64 * k4 + a65 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5 + - a76 * k6) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a81 * k1 + a83 * k3 + a84 * k4 + a85 * k5 + - a86 * k6 + - a87 * k7) - stage_limiter!(tmp, integrator, p, t + c8 * dt) - f(k8, tmp, p, t + c8 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b4 * k4 + b5 * k5 + b6 * k6 + b7 * k7 + - b8 * k8) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k9, u, p, t + dt) - integrator.stats.nf += 8 - integrator.fsallast = k9 - - return nothing -end - -function initialize!(integrator, cache::Stepanov5ConstantCache) - integrator.kshortsize = 7 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.fsallast = zero(integrator.fsalfirst) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -function perform_step!(integrator, cache::Stepanov5ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6 = cache - - k1 = integrator.fsalfirst - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - k5 = f(tmp, p, t + dt * c5) - tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(tmp, p, t + dt * c6) - u = uprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) - k7 = f(u, p, t + dt) - integrator.fsallast = k7 - integrator.stats.nf += 6 - - if integrator.opts.adaptive - @.. broadcast=false utilde=dt * (btilde1 * k1 + btilde2 * k2 + - btilde3 * k3 + btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.u = u -end - -function initialize!(integrator, cache::Stepanov5Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 7 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k7 - - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::Stepanov5Cache, repeat_step = false) - @unpack k1, k2, k3, k4, k5, k6, k7, tmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, b1, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k7, u, p, t + dt) - integrator.stats.nf += 6 - integrator.fsallast = k7 - - if integrator.opts.adaptive - utilde = dt * - (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 + btilde5 * k5 + - btilde6 * k6 + - btilde7 * k7) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - return nothing -end - -function initialize!(integrator, cache::SIR54ConstantCache) - integrator.kshortsize = 8 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.fsallast = zero(integrator.fsalfirst) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - @inbounds for i in 2:(integrator.kshortsize - 1) - integrator.k[i] = zero(integrator.fsalfirst) - end - integrator.k[integrator.kshortsize] = integrator.fsallast -end - -function perform_step!(integrator, cache::SIR54ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, b1, b2, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6, c7 = cache - - k1 = integrator.fsalfirst - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - k5 = f(tmp, p, t + dt * c5) - tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(tmp, p, t + dt * c6) - tmp = uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) - k7 = f(tmp, p, t + dt * c7) - u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + b6 * k6) - k8 = f(u, p, t + dt) - integrator.fsallast = k8 - integrator.stats.nf += 7 - - if integrator.opts.adaptive - utilde = dt * (btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + - btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.k[8] = k8 - integrator.u = u -end - -function initialize!(integrator, cache::SIR54Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 8 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.k[8] = cache.k8 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k8 - - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::SIR54Cache, repeat_step = false) - @unpack k1, k2, k3, k4, k5, k6, k7, k8, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, b1, b2, b3, b4, b5, b6, btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, c3, c4, c5, c6, c7 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + - a75 * k5 + a76 * k6) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 + b5 * k5 + - b6 * k6) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - f(k8, u, p, t + dt) - integrator.stats.nf += 7 - integrator.fsallast = k8 - - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * - (btilde1 * k1 + btilde2 * k2 + - btilde3 * k3 + btilde4 * k4 + - btilde5 * k5 + btilde6 * k6 + - btilde7 * k7) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - return nothing -end - -function initialize!(integrator, cache::Alshina2ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function perform_step!(integrator, cache::Alshina2ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, b1, b2, b1tilde, c2 = cache - - k1 = f(uprev, p, t) - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - u = uprev + dt * (b1 * k1 + b2 * k2) - - if integrator.opts.adaptive - utilde = dt * (b1tilde * k1) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.stats.nf += 2 - integrator.fsallast = k2 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.u = u -end - -function initialize!(integrator, cache::Alshina2Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 2 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k2 - - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::Alshina2Cache, repeat_step = false) - @unpack k1, k2, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, b1, b2, b1tilde, c2 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - f(k1, uprev, p, t) - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * integrator.fsalfirst) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - - @.. broadcast=false thread=thread u=uprev + - dt * (b1 * k1 + b2 * k2) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (b1tilde * k1) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - integrator.stats.nf += 2 - integrator.fsallast = k2 - - return nothing -end - -function initialize!(integrator, cache::Alshina3ConstantCache) - integrator.kshortsize = 3 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = zero(integrator.fsalfirst) - integrator.k[3] = integrator.fsallast -end - -function perform_step!(integrator, cache::Alshina3ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a32, b1, b2, b3, b2tilde, c2, c3 = cache - - k1 = f(uprev, p, t) - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - u = uprev + dt * (b1 * k1 + b2 * k2 + b3 * k3) - - if integrator.opts.adaptive - utilde = dt * (b2tilde * k2) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.stats.nf += 3 - integrator.fsallast = k3 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.u = u -end - -function initialize!(integrator, cache::Alshina3Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 3 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k3 - - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 -end - -function perform_step!(integrator, cache::Alshina3Cache, repeat_step = false) - @unpack k1, k2, k3, utilde, tmp, atmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a32, b1, b2, b3, b2tilde, c2, c3 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - f(k1, uprev, p, t) - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * (b1 * k1 + b2 * k2 + b3 * k3) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - if integrator.opts.adaptive - @.. broadcast=false thread=thread utilde=dt * (b2tilde * k2) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t, - thread) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.stats.nf += 3 - integrator.fsallast = k3 - - return nothing -end - -function initialize!(integrator, cache::Alshina6ConstantCache) - integrator.kshortsize = 7 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = zero(integrator.fsalfirst) - integrator.k[3] = zero(integrator.fsalfirst) - integrator.k[4] = zero(integrator.fsalfirst) - integrator.k[5] = zero(integrator.fsalfirst) - integrator.k[6] = zero(integrator.fsalfirst) - integrator.k[7] = integrator.fsallast -end - -function perform_step!(integrator, cache::Alshina6ConstantCache, repeat_step = false) - @unpack u, uprev, f, p, dt, t = integrator - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, - b1, b5, b6, b7, c2, c3, c4, c5, c6, c7 = cache - - k1 = f(uprev, p, t) - tmp = uprev + dt * (a21 * k1) - k2 = f(tmp, p, t + c2 * dt) - tmp = uprev + dt * (a31 * k1 + a32 * k2) - k3 = f(tmp, p, t + c3 * dt) - tmp = uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - k4 = f(tmp, p, t + dt * c4) - tmp = uprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - k5 = f(tmp, p, t + dt * c5) - tmp = uprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5) - k6 = f(tmp, p, t + dt * c6) - tmp = uprev + dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + a75 * k5 + a76 * k6) - k7 = f(tmp, p, t + dt * c7) - - integrator.fsallast = k7 - - u = uprev + dt * (b1 * k1 + b5 * k5 + b6 * k6 + b7 * k7) - - integrator.stats.nf += 7 - - integrator.k[1] = k1 - integrator.k[2] = k2 - integrator.k[3] = k3 - integrator.k[4] = k4 - integrator.k[5] = k5 - integrator.k[6] = k6 - integrator.k[7] = k7 - integrator.u = u -end - -function initialize!(integrator, cache::Alshina6Cache) - @unpack uprev, f, p, t = integrator - - integrator.kshortsize = 7 - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = cache.k1 - integrator.k[2] = cache.k2 - integrator.k[3] = cache.k3 - integrator.k[4] = cache.k4 - integrator.k[5] = cache.k5 - integrator.k[6] = cache.k6 - integrator.k[7] = cache.k7 - integrator.fsalfirst = cache.k1 - integrator.fsallast = cache.k7 -end - -function perform_step!(integrator, cache::Alshina6Cache, repeat_step = false) - @unpack k1, k2, k3, k4, k5, k6, k7, tmp, stage_limiter!, step_limiter!, thread = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, - b1, b5, b6, b7, c2, c3, c4, c5, c6, c7 = cache.tab - @unpack u, uprev, t, dt, f, p = integrator - - f(k1, uprev, p, t) - @.. broadcast=false thread=thread tmp=uprev + dt * (a21 * k1) - stage_limiter!(tmp, integrator, p, t + c2 * dt) - f(k2, tmp, p, t + c2 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a31 * k1 + a32 * k2) - stage_limiter!(tmp, integrator, p, t + c3 * dt) - f(k3, tmp, p, t + c3 * dt) - @.. broadcast=false thread=thread tmp=uprev + dt * (a41 * k1 + a42 * k2 + a43 * k3) - stage_limiter!(tmp, integrator, p, t + c4 * dt) - f(k4, tmp, p, t + c4 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4) - stage_limiter!(tmp, integrator, p, t + c5 * dt) - f(k5, tmp, p, t + c5 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + - a65 * k5) - stage_limiter!(tmp, integrator, p, t + c6 * dt) - f(k6, tmp, p, t + c6 * dt) - @.. broadcast=false thread=thread tmp=uprev + - dt * (a71 * k1 + a72 * k2 + a73 * k3 + a74 * k4 + - a75 * k5 + a76 * k6) - stage_limiter!(tmp, integrator, p, t + c7 * dt) - f(k7, tmp, p, t + c7 * dt) - @.. broadcast=false thread=thread u=uprev + - dt * - (b1 * k1 + b5 * k5 + b6 * k6 + b7 * k7) - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - integrator.stats.nf += 7 - integrator.fsallast = k7 - return nothing -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_tableaus.jl b/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_tableaus.jl deleted file mode 100644 index 4e9e0069a0..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/low_order_rk_tableaus.jl +++ /dev/null @@ -1,2186 +0,0 @@ -struct BS3ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - a32::T - a41::T - a42::T - a43::T - c1::T2 - c2::T2 - btilde1::T - btilde2::T - btilde3::T - btilde4::T -end - -""" -constructBogakiShampine3() - -Constructs the tableau object for the Bogakai-Shampine Order 2/3 method. -""" -function BS3ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - a21 = convert(T, 0.5) - a32 = convert(T, 0.75) - a41 = convert(T, 0.2222222222222222) - a42 = convert(T, 0.3333333333333333) - a43 = convert(T, 0.4444444444444444) - c1 = convert(T2, 0.5) - c2 = convert(T2, 0.75) - # b1 = convert(T,0.2916666666666667) - # b2 = convert(T,0.25) - # b3 = convert(T,0.3333333333333333) - # b4 = convert(T,0.125) - btilde1 = convert(T, 0.06944444444444445) - btilde2 = convert(T, -0.08333333333333333) - btilde3 = convert(T, -0.1111111111111111) - btilde4 = convert(T, 0.125) - BS3ConstantCache(a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4) -end - -""" -constructBogakiShampine3() - -Constructs the tableau object for the Bogakai-Shampine Order 2/3 method. -""" -function BS3ConstantCache(T::Type, T2::Type) - a21 = convert(T, 1 // 2) - a32 = convert(T, 3 // 4) - a41 = convert(T, 2 // 9) - a42 = convert(T, 1 // 3) - a43 = convert(T, 4 // 9) - c1 = convert(T2, 1 // 2) - c2 = convert(T2, 3 // 4) - # b1 = convert(T,7//24) - # b2 = convert(T,1//4) - # b3 = convert(T,1//3) - # b4 = convert(T,1//8) - btilde1 = convert(T, 5 // 72) - btilde2 = convert(T, -1 // 12) - btilde3 = convert(T, -1 // 9) - btilde4 = convert(T, 1 // 8) - BS3ConstantCache(a21, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, btilde4) -end - -struct OwrenZen3ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - c1::T2 - c2::T2 - btilde1::T - btilde2::T - btilde3::T - r13::T - r12::T - r23::T - r22::T - r33::T - r32::T -end - -function OwrenZen3ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - a21 = convert(T, 0.5217391304347826) - a31 = convert(T, -0.18133333333333335) - a32 = convert(T, 0.9813333333333333) - a41 = convert(T, 0.2152777777777778) - a42 = convert(T, 0.4592013888888889) - a43 = convert(T, 0.3255208333333333) - c1 = convert(T2, 0.5217391304347826) - c2 = convert(T2, 0.8) - # b1 = convert(T,0.041666666666666664) - # b2 = convert(T,0.9583333333333334) - btilde1 = convert(T, -0.1736111111111111) - btilde2 = convert(T, 0.4991319444444444) - btilde3 = convert(T, -0.3255208333333333) - r13 = convert(T, 0.5694444444444444) - r12 = convert(T, -1.3541666666666667) - r23 = convert(T, -0.9184027777777778) - r22 = convert(T, 1.3776041666666667) - r33 = convert(T, -0.6510416666666666) - r32 = convert(T, 0.9765625) - OwrenZen3ConstantCache(a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, - r13, r12, r23, r22, r33, r32) -end - -function OwrenZen3ConstantCache(T, T2) - a21 = convert(T, 12 // 23) - a31 = convert(T, -68 // 375) - a32 = convert(T, 368 // 375) - a41 = convert(T, 31 // 144) - a42 = convert(T, 529 // 1152) - a43 = convert(T, 125 // 384) - c1 = convert(T2, 12 // 23) - c2 = convert(T2, 4 // 5) - # b1 = convert(T,1//24) - # b2 = convert(T,23//24) - btilde1 = convert(T, -25 // 144) - btilde2 = convert(T, 575 // 1152) - btilde3 = convert(T, -125 // 384) - r13 = convert(T, 41 // 72) - r12 = convert(T, -65 // 48) - r23 = convert(T, -529 // 576) - r22 = convert(T, 529 // 384) - r33 = convert(T, -125 // 192) - r32 = convert(T, 125 // 128) - OwrenZen3ConstantCache(a21, a31, a32, a41, a42, a43, c1, c2, btilde1, btilde2, btilde3, - r13, r12, r23, r22, r33, r32) -end - -struct OwrenZen4ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a63::T - a64::T - a65::T - c1::T2 - c2::T2 - c3::T2 - c4::T2 - btilde1::T - btilde3::T - btilde4::T - btilde5::T - r14::T - r13::T - r12::T - r34::T - r33::T - r32::T - r44::T - r43::T - r42::T - r54::T - r53::T - r52::T - r64::T - r63::T - r62::T -end - -function OwrenZen4ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - a21 = convert(T, 0.16666666666666666) - a31 = convert(T, 0.03214024835646457) - a32 = convert(T, 0.26515704894083275) - a41 = convert(T, 0.6895990230002036) - a42 = convert(T, -1.6993690209647874) - a43 = convert(T, 1.6568288214939955) - a51 = convert(T, -0.09002509947964493) - a52 = convert(T, 0.6817777777777778) - a53 = convert(T, -0.2402791551882461) - a54 = convert(T, 0.5151931435567799) - a61 = convert(T, 0.08990252172070354) - a63 = convert(T, 0.4360623278236915) - a64 = convert(T, 0.1842858372687918) - a65 = convert(T, 0.2897493131868132) - c1 = convert(T2, 0.16666666666666666) - c2 = convert(T2, 0.2972972972972973) - c3 = convert(T2, 0.6470588235294118) - c4 = convert(T2, 0.8666666666666667) - # b1 = convert(T,0.27823691460055094) - # b3 = convert(T,-0.09428374655647383) - # b4 = convert(T,0.8160468319559229) - btilde1 = convert(T, 0.18833439287984743) - btilde3 = convert(T, -0.5303460743801653) - btilde4 = convert(T, 0.6317609946871311) - btilde5 = convert(T, -0.2897493131868132) - r14 = convert(T, -1.0513495872621479) - r13 = convert(T, 2.922894131082889) - r12 = convert(T, -2.7816420221000375) - r34 = convert(T, 2.4266369235379472) - r33 = convert(T, -5.725398502723277) - r32 = convert(T, 3.7348239070090217) - r44 = convert(T, -0.7705135914137909) - r43 = convert(T, 1.1724555082899983) - r42 = convert(T, -0.21765607960741548) - r54 = convert(T, -2.8643157295948325) - r53 = convert(T, 5.149132832816039) - r52 = convert(T, -1.9950677900343932) - r64 = convert(T, 2.2595419847328246) - r63 = convert(T, -3.519083969465649) - r62 = convert(T, 1.2595419847328244) - OwrenZen4ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, - btilde5, - r14, r13, r12, r34, r33, r32, r44, r43, r42, - r54, r53, r52, r64, r63, r62) -end - -function OwrenZen4ConstantCache(T, T2) - a21 = convert(T, 1 // 6) - a31 = convert(T, 44 // 1369) - a32 = convert(T, 363 // 1369) - a41 = convert(T, 3388 // 4913) - a42 = convert(T, -8349 // 4913) - a43 = convert(T, 8140 // 4913) - a51 = convert(T, -36764 // 408375) - a52 = convert(T, 767 // 1125) - a53 = convert(T, -32708 // 136125) - a54 = convert(T, 210392 // 408375) - a61 = convert(T, 1697 // 18876) - a63 = convert(T, 50653 // 116160) - a64 = convert(T, 299693 // 1626240) - a65 = convert(T, 3375 // 11648) - c1 = convert(T2, 1 // 6) - c2 = convert(T2, 11 // 37) - c3 = convert(T2, 11 // 17) - c4 = convert(T2, 13 // 15) - # b1 = convert(T,101//363) - # b3 = convert(T,-1369//14520) - # b4 = convert(T,11849//14520) - btilde1 = convert(T, 1185 // 6292) - btilde3 = convert(T, -4107 // 7744) - btilde4 = convert(T, 68493 // 108416) - btilde5 = convert(T, -3375 // 11648) - r14 = convert(T, -866577 // 824252) - r13 = convert(T, 1806901 // 618189) - r12 = convert(T, -104217 // 37466) - r34 = convert(T, 12308679 // 5072320) - r33 = convert(T, -2178079 // 380424) - r32 = convert(T, 861101 // 230560) - r44 = convert(T, -7816583 // 10144640) - r43 = convert(T, 6244423 // 5325936) - r42 = convert(T, -63869 // 293440) - r54 = convert(T, -624375 // 217984) - r53 = convert(T, 982125 // 190736) - r52 = convert(T, -1522125 // 762944) - r64 = convert(T, 296 // 131) - r63 = convert(T, -461 // 131) - r62 = convert(T, 165 // 131) - OwrenZen4ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - a61, a63, a64, a65, c1, c2, c3, c4, btilde1, btilde3, btilde4, - btilde5, - r14, r13, r12, r34, r33, r32, r44, r43, r42, - r54, r53, r52, r64, r63, r62) -end - -struct OwrenZen5ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - a81::T - a83::T - a84::T - a85::T - a86::T - a87::T - c1::T2 - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - btilde1::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - r15::T - r14::T - r13::T - r12::T - r35::T - r34::T - r33::T - r32::T - r45::T - r44::T - r43::T - r42::T - r55::T - r54::T - r53::T - r52::T - r65::T - r64::T - r63::T - r62::T - r75::T - r74::T - r73::T - r72::T - r85::T - r84::T - r83::T - r82::T -end - -function OwrenZen5ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - a21 = convert(T, 0.16666666666666666) - a31 = convert(T, 0.0625) - a32 = convert(T, 0.1875) - a41 = convert(T, 0.25) - a42 = convert(T, -0.75) - a51 = convert(T, -0.75) - a52 = convert(T, 3.75) - a53 = convert(T, -3.0) - a54 = convert(T, 0.5) - a61 = convert(T, 0.26895043731778423) - a62 = convert(T, -0.7084548104956269) - a63 = convert(T, 0.8658892128279884) - a64 = convert(T, 0.15462307371928363) - a65 = convert(T, 0.06184922948771345) - a71 = convert(T, -0.02947695035460993) - a72 = convert(T, 0.18500664893617022) - a73 = convert(T, 0.4802345261121857) - a74 = convert(T, -0.5337849069148937) - a75 = convert(T, -0.013090093085106383) - a76 = convert(T, 0.7861107753062541) - a81 = convert(T, 0.08783068783068783) - a83 = convert(T, 0.3006060606060606) - a84 = convert(T, 0.22777777777777777) - a85 = convert(T, 0.027777777777777776) - a86 = convert(T, 0.06218596218596219) - a87 = convert(T, 0.2938217338217338) - c1 = convert(T2, 0.16666666666666666) - c2 = convert(T2, 0.25) - c3 = convert(T2, 0.5) - c4 = convert(T2, 0.5) - c5 = convert(T2, 0.6428571428571429) - c6 = convert(T2, 0.875) - # b1 = convert(T,-0.1111111111111111) - # b3 = convert(T,1.2121212121212122) - # b4 = convert(T,-1.75) - # b5 = convert(T,-0.08333333333333333) - # b6 = convert(T,1.7323232323232323) - btilde1 = convert(T, -0.19894179894179895) - btilde3 = convert(T, 0.9115151515151515) - btilde4 = convert(T, -1.9777777777777779) - btilde5 = convert(T, -0.1111111111111111) - btilde6 = convert(T, 1.67013727013727) - btilde7 = convert(T, -0.2938217338217338) - r15 = convert(T, 1.892063492063492) - r14 = convert(T, -6.067155067155067) - r13 = convert(T, 7.282458282458283) - r12 = convert(T, -4.0195360195360195) - r35 = convert(T, -7.214545454545455) - r34 = convert(T, 20.676923076923078) - r33 = convert(T, -20.31142191142191) - r32 = convert(T, 7.14965034965035) - r45 = convert(T, 7.866666666666666) - r44 = convert(T, -18.78205128205128) - r43 = convert(T, 13.508547008547009) - r42 = convert(T, -2.3653846153846154) - r55 = convert(T, 2) - r54 = convert(T, -5.294871794871795) - r53 = convert(T, 4.534188034188034) - r52 = convert(T, -1.2115384615384615) - r65 = convert(T, -1.4924630924630924) - r64 = convert(T, 1.5785667324128863) - r63 = convert(T, 1.1958838881915805) - r62 = convert(T, -1.219801565955412) - r75 = convert(T, -7.051721611721612) - r74 = convert(T, 16.273203719357564) - r73 = convert(T, -11.978886071193763) - r72 = convert(T, 3.0512256973795435) - r85 = convert(T, 4) - r84 = convert(T, -8.384615384615385) - r83 = convert(T, 5.769230769230769) - r82 = convert(T, -1.3846153846153846) - OwrenZen5ConstantCache(a21, a31, a32, a41, a42, a51, a52, a53, - a54, a61, a62, a63, a64, a65, a71, a72, a73, - a74, a75, a76, a81, a83, a84, a85, a86, a87, - c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, - btilde6, btilde7, - r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, - r43, r42, r55, r54, r53, r52, r65, r64, r63, - r62, r75, r74, r73, r72, r85, r84, r83, r82) -end - -function OwrenZen5ConstantCache(T, T2) - a21 = convert(T, 1 // 6) - a31 = convert(T, 1 // 16) - a32 = convert(T, 3 // 16) - a41 = convert(T, 1 // 4) - a42 = convert(T, -3 // 4) - a43 = convert(T, 1) - a51 = convert(T, -3 // 4) - a52 = convert(T, 15 // 4) - a53 = convert(T, -3) - a54 = convert(T, 1 // 2) - a61 = convert(T, 369 // 1372) - a62 = convert(T, -243 // 343) - a63 = convert(T, 297 // 343) - a64 = convert(T, 1485 // 9604) - a65 = convert(T, 297 // 4802) - a71 = convert(T, -133 // 4512) - a72 = convert(T, 1113 // 6016) - a73 = convert(T, 7945 // 16544) - a74 = convert(T, -12845 // 24064) - a75 = convert(T, -315 // 24064) - a76 = convert(T, 156065 // 198528) - a81 = convert(T, 83 // 945) - a83 = convert(T, 248 // 825) - a84 = convert(T, 41 // 180) - a85 = convert(T, 1 // 36) - a86 = convert(T, 2401 // 38610) - a87 = convert(T, 6016 // 20475) - c1 = convert(T2, 1 // 6) - c2 = convert(T2, 1 // 4) - c3 = convert(T2, 1 // 2) - c4 = convert(T2, 1 // 2) - c5 = convert(T2, 9 // 14) - c6 = convert(T2, 7 // 8) - # b1 = convert(T,-1//9) - # b3 = convert(T,40//33) - # b4 = convert(T,-7//4) - # b5 = convert(T,-1//12) - # b6 = convert(T,343//198) - btilde1 = convert(T, -188 // 945) - btilde3 = convert(T, 752 // 825) - btilde4 = convert(T, -89 // 45) - btilde5 = convert(T, -1 // 9) - btilde6 = convert(T, 32242 // 19305) - btilde7 = convert(T, -6016 // 20475) - r15 = convert(T, 596 // 315) - r14 = convert(T, -4969 // 819) - r13 = convert(T, 17893 // 2457) - r12 = convert(T, -3292 // 819) - r35 = convert(T, -1984 // 275) - r34 = convert(T, 1344 // 65) - r33 = convert(T, -43568 // 2145) - r32 = convert(T, 5112 // 715) - r45 = convert(T, 118 // 15) - r44 = convert(T, -1465 // 78) - r43 = convert(T, 3161 // 234) - r42 = convert(T, -123 // 52) - r55 = convert(T, 2) - r54 = convert(T, -413 // 78) - r53 = convert(T, 1061 // 234) - r52 = convert(T, -63 // 52) - r65 = convert(T, -9604 // 6435) - r64 = convert(T, 2401 // 1521) - r63 = convert(T, 60025 // 50193) - r62 = convert(T, -40817 // 33462) - r75 = convert(T, -48128 // 6825) - r74 = convert(T, 96256 // 5915) - r73 = convert(T, -637696 // 53235) - r72 = convert(T, 18048 // 5915) - r85 = convert(T, 4) - r84 = convert(T, -109 // 13) - r83 = convert(T, 75 // 13) - r82 = convert(T, -18 // 13) - OwrenZen5ConstantCache(a21, a31, a32, a41, a42, a51, a52, a53, - a54, a61, a62, a63, a64, a65, a71, a72, a73, - a74, a75, a76, a81, a83, a84, a85, a86, a87, - c1, c2, c3, c4, c5, c6, btilde1, btilde3, btilde4, btilde5, - btilde6, btilde7, - r15, r14, r13, r12, r35, r34, r33, r32, r45, r44, - r43, r42, r55, r54, r53, r52, r65, r64, r63, - r62, r75, r74, r73, r72, r85, r84, r83, r82) -end - -struct Tsit5ConstantCache <: OrdinaryDiffEqConstantCache end -struct Tsit5ConstantCacheActual{T, T2} - c1::T2 - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T -end - -@fold function Tsit5ConstantCacheActual(::Type{T}, - ::Type{T2}) where {T <: CompiledFloats, - T2 <: CompiledFloats} - c1 = convert(T2, 0.161) - c2 = convert(T2, 0.327) - c3 = convert(T2, 0.9) - c4 = convert(T2, 0.9800255409045097) - c5 = convert(T2, 1) - c6 = convert(T2, 1) - a21 = convert(T, 0.161) - a31 = convert(T, -0.008480655492356989) - a32 = convert(T, 0.335480655492357) - a41 = convert(T, 2.8971530571054935) - a42 = convert(T, -6.359448489975075) - a43 = convert(T, 4.3622954328695815) - a51 = convert(T, 5.325864828439257) - a52 = convert(T, -11.748883564062828) - a53 = convert(T, 7.4955393428898365) - a54 = convert(T, -0.09249506636175525) - a61 = convert(T, 5.86145544294642) - a62 = convert(T, -12.92096931784711) - a63 = convert(T, 8.159367898576159) - a64 = convert(T, -0.071584973281401) - a65 = convert(T, -0.028269050394068383) - a71 = convert(T, 0.09646076681806523) - a72 = convert(T, 0.01) - a73 = convert(T, 0.4798896504144996) - a74 = convert(T, 1.379008574103742) - a75 = convert(T, -3.290069515436081) - a76 = convert(T, 2.324710524099774) - # b1 = convert(T,0.09468075576583945) - # b2 = convert(T,0.009183565540343254) - # b3 = convert(T,0.4877705284247616) - # b4 = convert(T,1.234297566930479) - # b5 = convert(T,-2.7077123499835256) - # b6 = convert(T,1.866628418170587) - # b7 = convert(T,0.015151515151515152) - btilde1 = convert(T, -0.00178001105222577714) - btilde2 = convert(T, -0.0008164344596567469) - btilde3 = convert(T, 0.007880878010261995) - btilde4 = convert(T, -0.1447110071732629) - btilde5 = convert(T, 0.5823571654525552) - btilde6 = convert(T, -0.45808210592918697) - btilde7 = convert(T, 0.015151515151515152) - - Tsit5ConstantCacheActual( - c1, c2, c3, c4, c5, c6, a21, a31, a32, a41, a42, a43, a51, a52, - a53, - a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, - btilde1, - btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) -end - -@fold function Tsit5ConstantCacheActual(::Type{T}, ::Type{T2}) where {T, T2} - c1 = convert(T2, 161 // 1000) - c2 = convert(T2, 327 // 1000) - c3 = convert(T2, 9 // 10) - c4 = convert(T2, - big".9800255409045096857298102862870245954942137979563024768854764293221195950761080302604") - c5 = convert(T2, 1) - c6 = convert(T2, 1) - a21 = convert(T, 161 // 1000) - a31 = convert(T, - big"-.8480655492356988544426874250230774675121177393430391537369234245294192976164141156943e-2") - a32 = convert(T, - big".3354806554923569885444268742502307746751211773934303915373692342452941929761641411569") - a41 = convert(T, - big"2.897153057105493432130432594192938764924887287701866490314866693455023795137503079289") - a42 = convert(T, - big"-6.359448489975074843148159912383825625952700647415626703305928850207288721235210244366") - a43 = convert(T, - big"4.362295432869581411017727318190886861027813359713760212991062156752264926097707165077") - a51 = convert(T, - big"5.325864828439256604428877920840511317836476253097040101202360397727981648835607691791") - a52 = convert(T, - big"-11.74888356406282787774717033978577296188744178259862899288666928009020615663593781589") - a53 = convert(T, - big"7.495539342889836208304604784564358155658679161518186721010132816213648793440552049753") - a54 = convert(T, - big"-.9249506636175524925650207933207191611349983406029535244034750452930469056411389539635e-1") - a61 = convert(T, - big"5.861455442946420028659251486982647890394337666164814434818157239052507339770711679748") - a62 = convert(T, - big"-12.92096931784710929170611868178335939541780751955743459166312250439928519268343184452") - a63 = convert(T, - big"8.159367898576158643180400794539253485181918321135053305748355423955009222648673734986") - a64 = convert(T, - big"-.7158497328140099722453054252582973869127213147363544882721139659546372402303777878835e-1") - a65 = convert(T, - big"-.2826905039406838290900305721271224146717633626879770007617876201276764571291579142206e-1") - a71 = convert(T, - big".9646076681806522951816731316512876333711995238157997181903319145764851595234062815396e-1") - a72 = convert(T, 1 // 100) - a73 = convert(T, - big".4798896504144995747752495322905965199130404621990332488332634944254542060153074523509") - a74 = convert(T, - big"1.379008574103741893192274821856872770756462643091360525934940067397245698027561293331") - a75 = convert(T, - big"-3.290069515436080679901047585711363850115683290894936158531296799594813811049925401677") - a76 = convert(T, - big"2.324710524099773982415355918398765796109060233222962411944060046314465391054716027841") - # b1 = convert(T,big".9468075576583945807478876255758922856117527357724631226139574065785592789071067303271e-1") - # b2 = convert(T,big".9183565540343253096776363936645313759813746240984095238905939532922955247253608687270e-2") - # b3 = convert(T,big".4877705284247615707855642599631228241516691959761363774365216240304071651579571959813") - # b4 = convert(T,big"1.234297566930478985655109673884237654035539930748192848315425833500484878378061439761") - # b5 = convert(T,big"-2.707712349983525454881109975059321670689605166938197378763992255714444407154902012702") - # b6 = convert(T,big"1.866628418170587035753719399566211498666255505244122593996591602841258328965767580089") - # b7 = convert(T,1//66) - btilde1 = convert(T, - big"-1.780011052225771443378550607539534775944678804333659557637450799792588061629796e-03") - btilde2 = convert(T, - big"-8.164344596567469032236360633546862401862537590159047610940604670770447527463931e-04") - btilde3 = convert(T, - big"7.880878010261996010314727672526304238628733777103128603258129604952959142646516e-03") - btilde4 = convert(T, - big"-1.44711007173262907537165147972635116720922712343167677619514233896760819649515e-01") - btilde5 = convert(T, - big"5.823571654525552250199376106520421794260781239567387797673045438803694038950012e-01") - btilde6 = convert(T, - big"-4.580821059291869466616365188325542974428047279788398179474684434732070620889539e-01") - btilde7 = convert(T, 1 // 66) - - Tsit5ConstantCacheActual( - c1, c2, c3, c4, c5, c6, a21, a31, a32, a41, a42, a43, a51, a52, - a53, - a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, - btilde1, - btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) -end - -""" -Coefficients for the polynomial -bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... - -These are the coefficients of the expanded form of the polynomials from - -Runge–Kutta pairs of order 5(4) satisfying only the first column -simplifying assumption - -Ch. Tsitouras -""" -@fold function Tsit5Interp(::Type{T}) where {T <: CompiledFloats} - r11 = convert(T, 1.0) - r12 = convert(T, -2.763706197274826) - r13 = convert(T, 2.9132554618219126) - r14 = convert(T, -1.0530884977290216) - - r22 = convert(T, 0.13169999999999998) - r23 = convert(T, -0.2234) - r24 = convert(T, 0.1017) - - r32 = convert(T, 3.9302962368947516) - r33 = convert(T, -5.941033872131505) - r34 = convert(T, 2.490627285651253) - - r42 = convert(T, -12.411077166933676) - r43 = convert(T, 30.33818863028232) - r44 = convert(T, -16.548102889244902) - - r52 = convert(T, 37.50931341651104) - r53 = convert(T, -88.1789048947664) - r54 = convert(T, 47.37952196281928) - - r62 = convert(T, -27.896526289197286) - r63 = convert(T, 65.09189467479366) - r64 = convert(T, -34.87065786149661) - - r72 = convert(T, 1.5) - r73 = convert(T, -4) - r74 = convert(T, 2.5) - - return r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, - r62, r63, r64, r72, r73, r74 -end - -""" -Coefficients for the polynomial -bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... - -These are the coefficients of the expanded form of the polynomials from - -Runge–Kutta pairs of order 5(4) satisfying only the first column -simplifying assumption - -Ch. Tsitouras -""" -@fold function Tsit5Interp(::Type{T}) where {T} - r11 = convert(T, big"0.999999999999999974283372471559910888475488471328") - r12 = convert(T, big"-2.763706197274825911336735930481400260916070804192") - r13 = convert(T, big"2.91325546182191274375068099306808") - r14 = convert(T, -1.0530884977290216) - - r22 = convert(T, big"0.13169999999999999727") - r23 = convert(T, big"-0.22339999999999999818") - r24 = convert(T, 0.1017) - - r32 = convert(T, big"3.93029623689475152850687446709813398") - r33 = convert(T, big"-5.94103387213150473470249202589458001") - r34 = convert(T, big"2.490627285651252793") - - r42 = convert(T, big"-12.411077166933676983734381540685453484102414134010752") - r43 = convert(T, big"30.3381886302823215981729903691836576") - r44 = convert(T, big"-16.54810288924490272") - - r52 = convert(T, big"37.50931341651103919496903965334519631242339792120440212") - r53 = convert(T, big"-88.1789048947664011014276693541209817") - r54 = convert(T, big"47.37952196281928122") - - r62 = convert(T, big"-27.896526289197287805948263144598643896") - r63 = convert(T, big"65.09189467479367152629021928716553658") - r64 = convert(T, big"-34.87065786149660974") - - r72 = convert(T, 1.5) - r73 = convert(T, -4) - r74 = convert(T, 2.5) - - return r11, r12, r13, r14, r22, r23, r24, r32, r33, r34, r42, r43, r44, r52, r53, r54, - r62, r63, r64, r72, r73, r74 -end - -struct BS5ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - c1::T2 - c2::T2 - c3::T2 - c4::T2 - c5::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - a81::T - a83::T - a84::T - a85::T - a86::T - a87::T - bhat1::T - bhat3::T - bhat4::T - bhat5::T - bhat6::T - btilde1::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - btilde8::T - c6::T2 - c7::T2 - c8::T2 - a91::T - a92::T - a93::T - a94::T - a95::T - a96::T - a97::T - a98::T - a101::T - a102::T - a103::T - a104::T - a105::T - a106::T - a107::T - a108::T - a109::T - a111::T - a112::T - a113::T - a114::T - a115::T - a116::T - a117::T - a118::T - a119::T - a1110::T - r016::T - r015::T - r014::T - r013::T - r012::T - r036::T - r035::T - r034::T - r033::T - r032::T - r046::T - r045::T - r044::T - r043::T - r042::T - r056::T - r055::T - r054::T - r053::T - r052::T - r066::T - r065::T - r064::T - r063::T - r062::T - r076::T - r075::T - r074::T - r073::T - r072::T - r086::T - r085::T - r084::T - r083::T - r082::T - r096::T - r095::T - r094::T - r093::T - r106::T - r105::T - r104::T - r103::T - r102::T - r116::T - r115::T - r114::T - r113::T - r112::T -end - -""" -An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine -Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 -""" -function BS5ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - c1 = convert(T2, 0.16666666666666666) - c2 = convert(T2, 0.2222222222222222) - c3 = convert(T2, 0.42857142857142855) - c4 = convert(T2, 0.6666666666666666) - c5 = convert(T2, 0.75) - - a21 = convert(T, 0.16666666666666666) - a31 = convert(T, 0.07407407407407407) - a32 = convert(T, 0.14814814814814814) - a41 = convert(T, 0.13338192419825073) - a42 = convert(T, -0.47230320699708456) - a43 = convert(T, 0.7674927113702624) - a51 = convert(T, 0.22895622895622897) - a52 = convert(T, -0.36363636363636365) - a53 = convert(T, 0.2937062937062937) - a54 = convert(T, 0.5076405076405076) - a61 = convert(T, 0.026500355113636364) - a62 = convert(T, 0.23011363636363635) - a63 = convert(T, 0.10772747760052448) - a64 = convert(T, 0.1602190777972028) - a65 = convert(T, 0.225439453125) - a71 = convert(T, 0.18159821692916506) - a72 = convert(T, -0.38707982536247293) - a73 = convert(T, 0.41288268560074054) - a74 = convert(T, 0.6409913191253497) - a75 = convert(T, -1.0121439383514517) - a76 = convert(T, 1.1637515420586695) - a81 = convert(T, 0.07279265873015874) - a83 = convert(T, 0.28662437773692473) - a84 = convert(T, 0.19513621794871794) - a85 = convert(T, 0.008638392857142857) - a86 = convert(T, 0.3595655806182122) - a87 = convert(T, 0.07724277210884353) - - bhat1 = convert(T, -0.00234375) - bhat3 = convert(T, 0.0103760754048583) - bhat4 = convert(T, -0.016490384615384615) - bhat5 = convert(T, 0.018984375) - bhat6 = convert(T, -0.010526315789473684) - # btilde1=convert(T,0.07084476451760402) - # btilde2=convert(T,0) - # btilde3=convert(T,0.2956730769230769) - # btilde4=convert(T,0.17965747482208388) - # btilde5=convert(T,0.029861111111111113) - # btilde6=convert(T,0.3462886755067825) - # btilde7=convert(T,0.07176240133870539) - btilde1 = convert(T, -0.0019478942125547064) - btilde3 = convert(T, 0.009048699186152193) - btilde4 = convert(T, -0.015478743126634073) - btilde5 = convert(T, 0.021222718253968254) - btilde6 = convert(T, -0.013276905111429694) - btilde7 = convert(T, -0.005480370770138146) - btilde8 = convert(T, 0.005912495780636172) - c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = BS5Interp( - T, - T2) - r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = BS5Interp_polyweights(T) - BS5ConstantCache(c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, - a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, - btilde4, btilde5, btilde6, btilde7, btilde8, c6, c7, c8, a91, a92, a93, - a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, - a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, - a1110, r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, - r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, - r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, - r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, - r114, r113, r112) -end - -""" -An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine -Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 -""" -function BS5ConstantCache(T::Type, T2::Type) - c1 = convert(T2, 1 // 6) - c2 = convert(T2, 2 // 9) - c3 = convert(T2, 3 // 7) - c4 = convert(T2, 2 // 3) - c5 = convert(T2, 3 // 4) - - a21 = convert(T, 1 // 6) - a31 = convert(T, 2 // 27) - a32 = convert(T, 4 // 27) - a41 = convert(T, 183 // 1372) - a42 = convert(T, -162 // 343) - a43 = convert(T, 1053 // 1372) - a51 = convert(T, 68 // 297) - a52 = convert(T, -4 // 11) - a53 = convert(T, 42 // 143) - a54 = convert(T, 1960 // 3861) - a61 = convert(T, 597 // 22528) - a62 = convert(T, 81 // 352) - a63 = convert(T, 63099 // 585728) - a64 = convert(T, 58653 // 366080) - a65 = convert(T, 4617 // 20480) - a71 = convert(T, 174197 // 959244) - a72 = convert(T, -30942 // 79937) - a73 = convert(T, 8152137 // 19744439) - a74 = convert(T, 666106 // 1039181) - a75 = convert(T, -29421 // 29068) - a76 = convert(T, 482048 // 414219) - a81 = convert(T, 587 // 8064) - a83 = convert(T, 4440339 // 15491840) - a84 = convert(T, 24353 // 124800) - a85 = convert(T, 387 // 44800) - a86 = convert(T, 2152 // 5985) - a87 = convert(T, 7267 // 94080) - - bhat1 = convert(T, -3 // 1280) - bhat3 = convert(T, 6561 // 632320) - bhat4 = convert(T, -343 // 20800) - bhat5 = convert(T, 243 // 12800) - bhat6 = convert(T, -1 // 95) - # btilde1=convert(T,2479//34992) - # btilde2=convert(T,0) - # btilde3=convert(T,123//416) - # btilde4=convert(T,612941//3411720) - # btilde5=convert(T,43//1440) - # btilde6=convert(T,2272//6561) - # btilde7=convert(T,79937//1113912) - btilde1 = convert(T, -3817 // 1959552) - btilde3 = convert(T, 140181 // 15491840) - btilde4 = convert(T, -4224731 // 272937600) - btilde5 = convert(T, 8557 // 403200) - btilde6 = convert(T, -57928 // 4363065) - btilde7 = convert(T, -23930231 // 4366535040) - btilde8 = convert(T, 3293 // 556956) - c6, c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, a1110 = BS5Interp( - T, - T2) - r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 = BS5Interp_polyweights(T) - BS5ConstantCache(c1, c2, c3, c4, c5, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a83, a84, - a85, a86, a87, bhat1, bhat3, bhat4, bhat5, bhat6, btilde1, btilde3, - btilde4, btilde5, btilde6, btilde7, btilde8, c6, c7, c8, a91, a92, a93, - a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, a106, a107, - a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, - a1110, r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, - r046, r045, r044, r043, r042, r056, r055, r054, r053, r052, r066, r065, - r064, r063, r062, r076, r075, r074, r073, r072, r086, r085, r084, r083, - r082, r096, r095, r094, r093, r106, r105, r104, r103, r102, r116, r115, - r114, r113, r112) -end - -""" -An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine -Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 - -Used in the lazy construction of the dense output - -k9, k10, k11 are not computed until called in the dense routine -""" -function BS5Interp(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - c6 = convert(T2, 0.5) - c7 = convert(T2, 0.8333333333333334) - c8 = convert(T2, 0.1111111111111111) - a91 = convert(T, 0.07405598958333333) - a92 = convert(T, 0) - a93 = convert(T, 0.28964485093442743) - a94 = convert(T, 0.12839214966168092) - a95 = convert(T, -0.003779296875) - a96 = convert(T, 0.014230019493177388) - a97 = convert(T, -0.03379371279761905) - a98 = convert(T, 0.03125) - a101 = convert(T, -0.06358724036162344) - a102 = convert(T, 0.5742461924818869) - a103 = convert(T, -0.06365063007249953) - a104 = convert(T, 0.043159777438314964) - a105 = convert(T, 0.8370112883898733) - a106 = convert(T, -0.34045447246719235) - a107 = convert(T, 0.04926503818334922) - a108 = convert(T, -0.006882677669165967) - a109 = convert(T, -0.19577394258960973) - a111 = convert(T, 0.0636090772400987) - a112 = convert(T, 0.01057854182854183) - a113 = convert(T, 0.06600100945670531) - a114 = convert(T, 0.02048391555358402) - a115 = convert(T, 0.003682270330219549) - a116 = convert(T, 0.155258632271002) - a117 = convert(T, -0.08509702513818027) - a118 = convert(T, 0.1) - a119 = convert(T, -0.1) - a1110 = convert(T, -0.12340531043086005) - - return c6, - c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, - a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, - a1110 -end - -""" -An Efficient Runge-Kutta (4,5) Pair by P.Bogacki and L.F.Shampine -Computers and Mathematics with Applications, Vol. 32, No. 6, 1996, pages 15 to 28 - -Used in the lazy construction of the dense output - -k9, k10, k11 are not computed until called in the dense routine -""" -function BS5Interp(T::Type, T2::Type) - c6 = convert(T2, 1 // 2) - c7 = convert(T2, 5 // 6) - c8 = convert(T2, 1 // 9) - a91 = convert(T, 455 // 6144) - a92 = convert(T, 0) - a93 = convert(T, 10256301 // 35409920) - a94 = convert(T, 2307361 // 17971200) - a95 = convert(T, -387 // 102400) - a96 = convert(T, 73 // 5130) - a97 = convert(T, -7267 // 215040) - a98 = convert(T, 1 // 32) - a101 = convert(T, -837888343715 // 13176988637184) - a102 = convert(T, 30409415 // 52955362) - a103 = convert(T, -48321525963 // 759168069632) - a104 = convert(T, 8530738453321 // 197654829557760) - a105 = convert(T, 1361640523001 // 1626788720640) - a106 = convert(T, -13143060689 // 38604458898) - a107 = convert(T, 18700221969 // 379584034816) - a108 = convert(T, -5831595 // 847285792) - a109 = convert(T, -5183640 // 26477681) - a111 = convert(T, 98719073263 // 1551965184000) - a112 = convert(T, 1307 // 123552) - a113 = convert(T, 4632066559387 // 70181753241600) - a114 = convert(T, 7828594302389 // 382182512025600) - a115 = convert(T, 40763687 // 11070259200) - a116 = convert(T, 34872732407 // 224610586200) - a117 = convert(T, -2561897 // 30105600) - a118 = convert(T, 1 // 10) - a119 = convert(T, -1 // 10) - a1110 = convert(T, -1403317093 // 11371610250) - - return c6, - c7, c8, a91, a92, a93, a94, a95, a96, a97, a98, a101, a102, a103, a104, a105, - a106, a107, a108, a109, a111, a112, a113, a114, a115, a116, a117, a118, a119, - a1110 -end - -""" -Coefficients for the polynomial -bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... - -These coefficients are taken from RKSuite - -Note that RKSuite has an error: r081 should be 0 -and r011 should be 1. This is pretty easy to spot -since the first order interpolation is linear from y₀. -""" -function BS5Interp_polyweights(T::Type{<:CompiledFloats}) - r016 = convert(T, -11.547607240534195) - r015 = convert(T, 36.89579791207878) - r014 = convert(T, -45.470343197183475) - r013 = convert(T, 27.298136302807084) - r012 = convert(T, -8.103191118438032) - - r036 = convert(T, -27.245925284262768) - r035 = convert(T, 74.85879078710211) - r034 = convert(T, -72.2759709558427) - r033 = convert(T, 28.38602193195626) - r032 = convert(T, -3.4362921012159933) - - r046 = convert(T, -14.307769126529058) - r045 = convert(T, 38.240038148817945) - r044 = convert(T, -35.469854845413806) - r043 = convert(T, 13.060399314592578) - r042 = convert(T, -1.3276772735189397) - - r056 = convert(T, -0.7296779223862557) - r055 = convert(T, 1.9817123385873385) - r054 = convert(T, -1.964240395021645) - r053 = convert(T, 0.8847786781120115) - r052 = convert(T, -0.16393430643430643) - - r066 = convert(T, 19.121088881250603) - r065 = convert(T, -65.9928405785889) - r064 = convert(T, 77.4690381021765) - r063 = convert(T, -34.163041154825144) - r062 = convert(T, 3.9253203306051474) - - r076 = convert(T, -14.676126700680273) - r075 = convert(T, 42.17455357142857) - r074 = convert(T, -42.4062818877551) - r073 = convert(T, 16.83892431972789) - r072 = convert(T, -1.853826530612245) - - r086 = convert(T, 19.453125) - r085 = convert(T, -54.359375) - r084 = convert(T, 53.671875) - r083 = convert(T, -21.078125) - r082 = convert(T, 2.3125) - - r096 = convert(T, 18.333333333333332) - r095 = convert(T, -39) - r094 = convert(T, 23) - r093 = convert(T, -2.3333333333333335) - - r106 = convert(T, -23.400440940191388) - r105 = convert(T, 70.20132282057416) - r104 = convert(T, -73.55422182095978) - r103 = convert(T, 30.106238940962648) - r102 = convert(T, -3.3528990003856314) - - r116 = convert(T, 35) - r115 = convert(T, -105) - r114 = convert(T, 117) - r113 = convert(T, -59) - r112 = convert(T, 12) - - return r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, - r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, - r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, - r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 -end - -""" -Coefficients for the polynomial -bᵢΘ = ri1*Θ + ri2*Θ^2 + ri3*Θ^3 + ... - -These coefficients are taken from RKSuite - -Note that RKSuite has an error: r081 should be 0 -and r011 should be 1. This is pretty easy to spot -since the first order interpolation is linear from y₀. -""" -function BS5Interp_polyweights(T::Type) - r016 = convert(T, -12134338393 // 1050809760) - r015 = convert(T, 12923488183 // 350269920) - r014 = convert(T, -2722545893 // 59875200) - r013 = convert(T, 35856435071 // 1313512200) - r012 = convert(T, -3547880131 // 437837400) - - r036 = convert(T, -33197340367 // 1218433216) - r035 = convert(T, 65150312289 // 870309440) - r034 = convert(T, -27096444225 // 374902528) - r033 = convert(T, 4323308999 // 152304152) - r032 = convert(T, -1046723109 // 304608304) - - r046 = convert(T, -284800997201 // 19905339168) - r045 = convert(T, 6343174409579 // 165877826400) - r044 = convert(T, -201150852119 // 5671036800) - r043 = convert(T, 3249645975331 // 248816739600) - r042 = convert(T, -55058055073 // 41469456600) - - r056 = convert(T, -540919 // 741312) - r055 = convert(T, 85695583 // 43243200) - r054 = convert(T, -2903933 // 1478400) - r053 = convert(T, 3586937 // 4054050) - r052 = convert(T, -1772261 // 10810800) - - r066 = convert(T, 7157998304 // 374350977) - r065 = convert(T, -41174140576 // 623918295) - r064 = convert(T, 413114104 // 5332635) - r063 = convert(T, -9134977024 // 267393555) - r062 = convert(T, 2449079168 // 623918295) - - r076 = convert(T, -138073 // 9408) - r075 = convert(T, 94471 // 2240) - r074 = convert(T, -1329861 // 31360) - r073 = convert(T, 792103 // 47040) - r072 = convert(T, -7267 // 3920) - - r086 = convert(T, 1245 // 64) - r085 = convert(T, -3479 // 64) - r084 = convert(T, 3435 // 64) - r083 = convert(T, -1349 // 64) - r082 = convert(T, 37 // 16) - - r096 = convert(T, 55 // 3) - r095 = convert(T, -39) - r094 = convert(T, 23) - r093 = convert(T, -7 // 3) - - r106 = convert(T, -1774004627 // 75810735) - r105 = convert(T, 1774004627 // 25270245) - r104 = convert(T, -26477681 // 359975) - r103 = convert(T, 11411880511 // 379053675) - r102 = convert(T, -423642896 // 126351225) - - r116 = convert(T, 35) - r115 = convert(T, -105) - r114 = convert(T, 117) - r113 = convert(T, -59) - r112 = convert(T, 12) - - return r016, r015, r014, r013, r012, r036, r035, r034, r033, r032, r046, r045, r044, - r043, r042, r056, r055, r054, r053, r052, r066, r065, r064, r063, r062, r076, - r075, r074, r073, r072, r086, r085, r084, r083, r082, r096, r095, r094, r093, - r106, r105, r104, r103, r102, r116, r115, r114, r113, r112 -end - -struct DP5ConstantCache <: OrdinaryDiffEqConstantCache end -struct DP5ConstantCacheActual{T, T2} - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a73::T - a74::T - a75::T - a76::T - btilde1::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - c1::T2 - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - d1::T - d3::T - d4::T - d5::T - d6::T - d7::T -end - -@fold function DP5ConstantCacheActual(::Type{T}, - ::Type{T2}) where {T <: CompiledFloats, - T2 <: - CompiledFloats} - a21 = convert(T, 0.2) - a31 = convert(T, 0.075) - a32 = convert(T, 0.225) - a41 = convert(T, 0.9777777777777777) - a42 = convert(T, -3.7333333333333334) - a43 = convert(T, 3.5555555555555554) - a51 = convert(T, 2.9525986892242035) - a52 = convert(T, -11.595793324188385) - a53 = convert(T, 9.822892851699436) - a54 = convert(T, -0.2908093278463649) - a61 = convert(T, 2.8462752525252526) - a62 = convert(T, -10.757575757575758) - a63 = convert(T, 8.906422717743473) - a64 = convert(T, 0.2784090909090909) - a65 = convert(T, -0.2735313036020583) - a71 = convert(T, 0.09114583333333333) - a73 = convert(T, 0.44923629829290207) - a74 = convert(T, 0.6510416666666666) - a75 = convert(T, -0.322376179245283) - a76 = convert(T, 0.13095238095238096) - # b1 = convert(T,0.08991319444444444) - # b3 = convert(T,0.4534890685834082) - # b4 = convert(T,0.6140625) - # b5 = convert(T,-0.2715123820754717) - # b6 = convert(T,0.08904761904761904) - # b7 = convert(T,0.025) - btilde1 = convert(T, -0.0012326388888888888) - btilde3 = convert(T, 0.0042527702905061394) - btilde4 = convert(T, -0.03697916666666667) - btilde5 = convert(T, 0.05086379716981132) - btilde6 = convert(T, -0.0419047619047619) - btilde7 = convert(T, 0.025) - c1 = convert(T2, 0.2) - c2 = convert(T2, 0.3) - c3 = convert(T2, 0.8) - c4 = convert(T2, 0.8888888888888888) - c5 = convert(T2, 1) - c6 = convert(T2, 1) - d1, d3, d4, d5, d6, d7 = DP5_dense_ds(T) - DP5ConstantCacheActual(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, - a64, - a65, a71, a73, a74, a75, a76, btilde1, btilde3, btilde4, btilde5, - btilde6, btilde7, c1, c2, c3, c4, c5, c6, d1, d3, d4, d5, d6, d7) -end - -@fold function DP5_dense_ds(::Type{T}) where {T <: CompiledFloats} - d1 = convert(T, -1.1270175653862835) - d3 = convert(T, 2.675424484351598) - d4 = convert(T, -5.685526961588504) - d5 = convert(T, 3.5219323679207912) - d6 = convert(T, -1.7672812570757455) - d7 = convert(T, 2.382468931778144) - return d1, d3, d4, d5, d6, d7 -end - -@fold function DP5ConstantCacheActual(::Type{T}, ::Type{T2}) where {T, T2} - a21 = convert(T, 1 // 5) - a31 = convert(T, 3 // 40) - a32 = convert(T, 9 // 40) - a41 = convert(T, 44 / 45) - a42 = convert(T, -56 // 15) - a43 = convert(T, 32 // 9) - a51 = convert(T, 19372 // 6561) - a52 = convert(T, -25360 // 2187) - a53 = convert(T, 64448 // 6561) - a54 = convert(T, -212 // 729) - a61 = convert(T, 9017 // 3168) - a62 = convert(T, -355 // 33) - a63 = convert(T, 46732 // 5247) - a64 = convert(T, 49 // 176) - a65 = convert(T, -5103 // 18656) - a71 = convert(T, 35 // 384) - a73 = convert(T, 500 // 1113) - a74 = convert(T, 125 // 192) - a75 = convert(T, -2187 // 6784) - a76 = convert(T, 11 // 84) - # b1 = convert(T,5179//57600) - # b3 = convert(T,7571//16695) - # b4 = convert(T,393//640) - # b5 = convert(T,-92097//339200) - # b6 = convert(T,187//2100) - # b7 = convert(T,1//40) - btilde1 = convert(T, -71 // 57600) - btilde3 = convert(T, 71 // 16695) - btilde4 = convert(T, -71 // 1920) - btilde5 = convert(T, 17253 // 339200) - btilde6 = convert(T, -22 // 525) - btilde7 = convert(T, 1 // 40) - c1 = convert(T2, 1 // 5) - c2 = convert(T2, 3 // 10) - c3 = convert(T2, 4 // 5) - c4 = convert(T2, 8 // 9) - c5 = convert(T2, 1) - c6 = convert(T2, 1) - d1, d3, d4, d5, d6, d7 = DP5_dense_ds(T) - DP5ConstantCacheActual(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, - a64, - a65, a71, a73, a74, a75, a76, btilde1, btilde3, btilde4, btilde5, - btilde6, btilde7, c1, c2, c3, c4, c5, c6, d1, d3, d4, d5, d6, d7) -end - -@fold function DP5_dense_ds(::Type{T}) where {T} - d1 = convert(T, -12715105075 // 11282082432) - d3 = convert(T, 87487479700 // 32700410799) - d4 = convert(T, -10690763975 // 1880347072) - d5 = convert(T, 701980252875 // 199316789632) - d6 = convert(T, -1453857185 // 822651844) - d7 = convert(T, 69997945 // 29380423) - return d1, d3, d4, d5, d6, d7 -end - -#= -function DP5_dense_bs(T) - b1 = convert(T,5179//57600) - b3 = convert(T,7571//16695) - b4 = convert(T,393//640) - b5 = convert(T,-92097//339200) - b6 = convert(T,187//2100) - b7 = convert(T,1//40) - return b1,b3,b4,b5,b6,b7 -end -=# - -""" -An Optimized Runge-Kutta method for the solution of Orbital Problems -by Z.A. Anastassi and T.E. Simos -Journal of Computational and Applied Mathematics, Volume 175, Issue 1, 1 March 2005, Pages 1 to 9. -""" -struct Anas5ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - b1::T - b3::T - b4::T - b5::T - b6::T -end - -function Anas5ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - a21 = convert(T, 0.1) - a31 = convert(T, -0.2222222222222222) - a32 = convert(T, 0.5555555555555556) - a41 = convert(T, 3.111111111111111) - a42 = convert(T, -4.444444444444444) - a43 = convert(T, 2.0) - a51 = convert(T, -1.409625) - a52 = convert(T, 2.1375) - a53 = convert(T, -0.2295) - a54 = convert(T, 0.401625) - a61 = convert(T, -4.0) - a62 = convert(T, 5.0) - a63 = convert(T, 0.0) - a64 = convert(T, 0.0) - a65 = convert(T, 0.0) - c2 = convert(T2, 0.1) - c3 = convert(T2, 0.3333333333333333) - c4 = convert(T2, 0.6666666666666667) - c5 = convert(T2, 0.9) - c6 = convert(T2, 1) - b1 = convert(T, 0.1064814814814815) - b3 = convert(T, 0.4632352941176471) - b4 = convert(T, 0.1607142857142857) - b5 = convert(T, 0.3112356053532524) - b6 = convert(T, -0.04166666666666667) - Anas5ConstantCache( - a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6) -end - -function Anas5ConstantCache(T, T2) - a21 = convert(T, 1 // 10) - a31 = convert(T, -2 // 9) - a32 = convert(T, 5 // 9) - a41 = convert(T, 28 // 9) - a42 = convert(T, -40 // 9) - a43 = convert(T, 2 // 1) - a51 = convert(T, -11277 // 8000) - a52 = convert(T, 171 // 80) - a53 = convert(T, -459 // 2000) - a54 = convert(T, 3213 // 8000) - a61 = convert(T, -4 // 1) - a62 = convert(T, 5 // 1) - a63 = convert(T, 0 // 1) - a64 = convert(T, 0 // 1) - a65 = convert(T, 0 // 1) - c2 = convert(T2, 1 // 10) - c3 = convert(T2, 1 // 3) - c4 = convert(T2, 2 // 3) - c5 = convert(T2, 9 // 10) - c6 = convert(T2, 1 // 1) - b1 = convert(T, 23 // 216) - b3 = convert(T, 63 // 136) - b4 = convert(T, 9 // 56) - b5 = convert(T, 1000 // 3213) - b6 = convert(T, -1 // 24) - Anas5ConstantCache( - a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, c2, c3, c4, c5, c6, b1, b3, b4, b5, b6) -end - -struct PSRK4p7q6ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - - b1::T - b2::T - b3::T - b4::T - b5::T - b6::T - - c2::T1 - c3::T1 - c4::T1 - c5::T1 - c6::T1 -end - -function PSRK4p7q6ConstantCache(T::Type{<:CompiledFloats}, T1::Type{<:CompiledFloats}) - a21 = convert(T, 0.23593376536652) - a31 = convert(T, 0.34750735658424) - a32 = convert(T, -0.13561935398346) - a41 = convert(T, -0.20592852403227) - a42 = convert(T, 1.89179076622108) - a43 = convert(T, -0.89775024478958) - a51 = convert(T, -0.09435493281455) - a52 = convert(T, 1.75617141223762) - a53 = convert(T, -0.96707850476948) - a54 = convert(T, 0.06932825997989) - a61 = convert(T, 0.14157883255197) - a62 = convert(T, -1.17039696277833) - a63 = convert(T, 1.30579112376331) - a64 = convert(T, -2.20354136855289) - a65 = convert(T, 2.92656837501595) - - b1 = convert(T, 0.07078941627598) - b2 = convert(T, 0.87808570611881) - b3 = convert(T, -0.44887512239479) - b4 = convert(T, -0.44887512239479) - b5 = convert(T, 0.87808570611881) - b6 = convert(T, 0.07078941627598) - - c2 = convert(T1, 0.23593376536652) - c3 = convert(T1, 0.21188800260078) - c4 = convert(T1, 0.78811199739923) - c5 = convert(T1, 0.76406623463348) - c6 = convert(T1, 1.0) - - PSRK4p7q6ConstantCache( - a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, - b1, b2, b3, b4, b5, b6, - c2, c3, c4, c5, c6) -end - -struct PSRK3p6q5ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - - b1::T - b2::T - b3::T - b4::T - b5::T - - c2::T1 - c3::T1 - c4::T1 - c5::T1 -end - -function PSRK3p6q5ConstantCache(T::Type{<:CompiledFloats}, T1::Type{<:CompiledFloats}) - a21 = convert(T, 0.13502027922909) - a31 = convert(T, -0.47268213605237) - a32 = convert(T, 1.05980250415419) - a41 = convert(T, -1.21650460595689) - a42 = convert(T, 2.16217630216753) - a43 = convert(T, -0.37234592426536) - a51 = convert(T, 0.33274443036387) - a52 = convert(T, -0.20882668296587) - a53 = convert(T, 1.87865617737921) - a54 = convert(T, -1.00257392477721) - - b1 = convert(T, 0.04113894457092) - b2 = convert(T, 0.26732123194414) - b3 = convert(T, 0.86700906289955) - b4 = convert(T, -0.30547139552036) - b5 = convert(T, 0.13000215610576) - - c2 = convert(T1, 0.13502027922909) - c3 = convert(T1, 0.58712036810182) - c4 = convert(T1, 0.57332577194528) - c5 = convert(T1, 1.0) - - PSRK3p6q5ConstantCache( - a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - b1, b2, b3, b4, b5, - c2, c3, c4, c5) -end - -struct PSRK3p5q4ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - - b1::T - b2::T - b3::T - b4::T - - c2::T1 - c3::T1 - c4::T1 -end - -function PSRK3p5q4ConstantCache(T::Type, T1::Type) - a21 = T(3 // 8) - a31 = T(11 // 12) - a32 = T(-2 // 3) - a41 = T(-1 // 12) - a42 = T(11 // 6) - a43 = T(-3 // 4) - - b1 = T(1 // 9) - b2 = T(8 // 9) - b3 = T(-2 // 9) - b4 = T(2 // 9) - - c2 = T1(3 // 8) - c3 = T1(1 // 4) - c4 = T1(1) - - PSRK3p5q4ConstantCache( - a21, a31, a32, a41, a42, a43, - b1, b2, b3, b4, - c2, c3, c4) -end - -struct MSRK5ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a43::T - a51::T - a53::T - a54::T - a61::T - a63::T - a64::T - a65::T - a71::T - a73::T - a74::T - a75::T - a76::T - a81::T - a83::T - a84::T - a85::T - a86::T - a87::T - - b1::T # == a_{9i} ∀ i=1:8 - b4::T - b5::T - b6::T - b7::T - b8::T - - c2::T1 - c3::T1 - c4::T1 - c5::T1 - c6::T1 - c7::T1 - c8::T1 -end - -# Use rational numbers for testing. Define another function that defines the tab using floats. -function MSRK5ConstantCache(T::Type, T1::Type) - a21 = T(4 // 45) - a31 = T(1 // 30) - a32 = T(1 // 10) - a41 = T(1 // 20) - a43 = T(3 // 20) - a51 = T(1 // 2) - a53 = T(-15 // 8) - a54 = T(15 // 8) - a61 = T(-11 // 135) - a63 = T(23 // 45) - a64 = T(-2 // 27) - a65 = T(8 // 45) - a71 = T(5 // 108) - a73 = T(35 // 72) - a74 = T(-59 // 216) - a75 = T(-25 // 27) - a76 = T(3 // 2) - a81 = T(31 // 128) - a83 = T(-7563 // 4480) - a84 = T(233 // 112) - a85 = T(3461 // 2240) - a86 = T(-765 // 448) - a87 = T(153 // 320) - b1 = T(29 // 456) - b4 = T(11 // 38) - b5 = T(2 // 27) - b6 = T(11 // 40) - b7 = T(4 // 19) - b8 = T(224 // 2565) - c2 = T1(4 // 45) - c3 = T1(2 // 15) - c4 = T1(1 // 5) - c5 = T1(1 // 2) - c6 = T1(8 // 15) - c7 = T1(5 // 6) - c8 = T1(19 // 20) - - MSRK5ConstantCache( - a21, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, - a74, a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, - c2, c3, c4, c5, c6, c7, c8) -end - -struct MSRK6ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache - a21::T - a32::T - a41::T - a43::T - a51::T - a53::T - a54::T - a61::T - a63::T - a64::T - a65::T - a71::T - a73::T - a74::T - a75::T - a76::T - a81::T - a83::T - a84::T - a85::T - a86::T - a87::T - - b1::T - b4::T - b5::T - b6::T - b7::T - b8::T - - c2::T1 - c3::T1 - c4::T1 - c5::T1 - c6::T1 - c7::T1 - c8::T1 -end - -function MSRK6ConstantCache(T::Type, T1::Type) - a21 = T(1 // 14) - a32 = T(1 // 7) - a41 = T(3 // 56) - a43 = T(9 // 56) - a51 = T(29 // 72) - a53 = T(-35 // 24) - a54 = T(14 // 9) - a61 = T(-17 // 56) - a63 = T(93 // 56) - a64 = T(-8 // 7) - a65 = T(3 // 7) - a71 = T(199 // 1372) - a73 = T(-195 // 196) - a74 = T(1259 // 784) - a75 = T(-3855 // 5488) - a76 = T(45 // 56) - a81 = T(4903 // 25596) - a83 = T(4487 // 2844) - a84 = T(-255101 // 102384) - a85 = T(33847 // 11376) - a86 = T(-94325 // 51192) - a87 = T(3773 // 6399) - b1 = T(16 // 243) - b4 = T(16807 // 53460) - b5 = T(53 // 300) - b6 = T(2401 // 12150) - b7 = T(2401 // 12150) - b8 = T(79 // 1650) - c2 = T1(1 // 14) - c3 = T1(1 // 7) - c4 = T1(3 // 14) - c5 = T1(1 // 2) - c6 = T1(9 // 14) - c7 = T1(6 // 7) - c8 = T1(1) - - MSRK6ConstantCache( - a21, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, - a75, a76, a81, a83, a84, a85, a86, a87, b1, b4, b5, b6, b7, b8, c2, - c3, c4, c5, c6, c7, c8) -end - -struct Stepanov5ConstantCache{T, T1} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - - b1::T - # b2::T - b3::T - b4::T - b5::T - b6::T - - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - - c2::T1 - c3::T1 - c4::T1 - c5::T1 - c6::T1 -end - -# Use rational numbers for testing. Define another function that defines the tab using floats. -function Stepanov5ConstantCache(T::Type, T1::Type) - a21 = T(1 // 5) - a31 = T(21 // 338) - a32 = T(441 // 1690) - a41 = T(639 // 392) - a42 = T(-729 // 140) - a43 = T(1755 // 392) - a51 = T(4878991 // 1693440) - a52 = T(-16601 // 1792) - a53 = T(210067 // 28224) - a54 = T(-1469 // 17280) - a61 = T(13759919 // 4230954) - a62 = T(-2995 // 287) - a63 = T(507312091 // 61294590) - a64 = T(-22 // 405) - a65 = T(-7040 // 180687) - b1 = T(1441 // 14742) - # b2 = T(0) - b3 = T(114244 // 234927) - b4 = T(118 // 81) - b5 = T(-12800 // 4407) - b6 = T(41 // 22) - - btilde1 = T(-1 // 273) - btilde2 = T(0) - btilde3 = T(2197 // 174020) - btilde4 = T(-4 // 15) - btilde5 = T(1280 // 1469) - btilde6 = T(-33743 // 52712) - btilde7 = T(127 // 4792) - - c2 = T1(1 // 5) - c3 = T1(21 // 65) - c4 = T1(9 // 10) - c5 = T1(39 // 40) - c6 = T1(1 // 1) - - Stepanov5ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, - a64, a65, b1, b3, b4, b5, b6, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, - c2, c3, c4, c5, c6) -end - -struct SIR54ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - - b1::T - b2::T - b3::T - b4::T - b5::T - b6::T - - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 -end - -function SIR54ConstantCache(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - a21 = convert(T, 0.224991857145594237) - a31 = convert(T, 0.0891533610320671103) - a32 = convert(T, 0.238960211116888553) - a41 = convert(T, 1.30502239863058047) - a42 = convert(T, -5.50177549088639896) - a43 = convert(T, 5.14113139529316096) - a51 = convert(T, 1.76234012927544337) - a52 = convert(T, -7.44800428470202672) - a53 = convert(T, 6.70879999021246612) - a54 = convert(T, -0.0341377330357163063) - a61 = convert(T, 1.87412911619818746) - a62 = convert(T, -7.91467977711770718) - a63 = convert(T, 7.07985467092264069) - a64 = convert(T, -0.0244945338238275367) - a65 = convert(T, -0.0148094761792934300) - a71 = convert(T, 0.0986971498551664256) - a72 = convert(T, 0.00100729346874150652) - a73 = convert(T, 0.495118366873759549) - a74 = convert(T, 3.93767069618687179) - a75 = convert(T, -13.7395424087173685) - a76 = convert(T, 10.2070489023328292) - - b1 = convert(T, 0.0986971498551664256) - b2 = convert(T, 0.00100729346874150652) - b3 = convert(T, 0.495118366873759549) - b4 = convert(T, 3.93767069618687179) - b5 = convert(T, -13.7395424087173685) - b6 = convert(T, 10.2070489023328292) - - btilde1 = convert(T, 0.008811109678338494) - btilde2 = convert(T, 0.00011407564162559992) - btilde3 = convert(T, -0.029774887187671295) - btilde4 = convert(T, 9.643100938483734) - btilde5 = convert(T, -8.034112166420506) - btilde6 = convert(T, 6.31615797738573) - btilde7 = convert(T, -0.05) - - c2 = convert(T2, 0.224991857145594237) - c3 = convert(T2, 0.328113572148955663) - c4 = convert(T2, 0.944378303037342471) - c5 = convert(T2, 0.988998101750166470) - c6 = convert(T2, 1.0) - c7 = convert(T2, 1.0) - - SIR54ConstantCache( - a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, a71, a72, a73, a74, a75, a76, b1, b2, b3, b4, b5, b6, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, c2, - c3, c4, c5, c6, c7) -end - -struct Alshina2ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - - b1::T - b2::T - b1tilde::T - - c2::T2 -end - -function Alshina2ConstantCache(T, T2) - a21 = convert(T, 0.6666666666666666) - - b1 = convert(T, 0.25) - b2 = convert(T, 0.75) - b1tilde = convert(T, 1.0) - - c2 = convert(T2, 0.666666666666666) - - Alshina2ConstantCache(a21, b1, b2, b1tilde, c2) -end - -struct Alshina3ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - # a31::T - a32::T - - b1::T - b2::T - b3::T - b2tilde::T - - c2::T2 - c3::T2 -end - -function Alshina3ConstantCache(T, T2) - a21 = convert(T, 0.5) - # a31 = convert(T, 0.0) - a32 = convert(T, 0.75) - - b1 = convert(T, 0.2222222222222222) - b2 = convert(T, 0.3333333333333333) - b3 = convert(T, 0.4444444444444444) - b2tilde = convert(T, 0.4444444444444444) - - c2 = convert(T2, 0.5) - c3 = convert(T2, 0.75) - - Alshina3ConstantCache(a21, a32, b1, b2, b3, b2tilde, c2, c3) -end - -struct Alshina6ConstantCache{T, T2} <: OrdinaryDiffEqConstantCache - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - - b1::T - # b2::T - # b3::T - # b4::T - b5::T - b6::T - b7::T - - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 -end - -function Alshina6ConstantCache(T, T2) - a21 = convert(T, 0.5714285714285714) - a31 = convert(T, 1.0267857142857142) - a32 = convert(T, -0.3125) - a41 = convert(T, 0.9349206349206349) - a42 = convert(T, 0.2777777777777778) - a43 = convert(T, -0.35555555555555557) - a51 = convert(T, 0.18002567144208434) - a52 = convert(T, 0.14737940683961614) - a53 = convert(T, 0.016070163293314288) - a54 = convert(T, -0.0670820393249937) - a61 = convert(T, -0.07979765856603138) - a62 = convert(T, 0.025290591998992584) - a63 = convert(T, -0.3516326202266813) - a64 = convert(T, 0.3207294901687516) - a65 = convert(T, 0.8090169943749475) - a71 = convert(T, 0.4988599356197352) - a72 = convert(T, -0.8633499941930429) - a73 = convert(T, 1.6778122846668349) - a74 = convert(T, -1.2682372542187894) - a75 = convert(T, -0.42705098312484235) - a76 = convert(T, 1.381966011250105) - - b1 = convert(T, 0.08333333333333333) - # b2 = convert(T, 0.0) - # b3 = convert(T, 0.0) - # b4 = convert(T, 0.0) - b5 = convert(T, 0.4166666666666667) - b6 = convert(T, 0.4166666666666667) - b7 = convert(T, 0.08333333333333333) - - c2 = convert(T2, 0.5714285714285714) - c3 = convert(T2, 0.7142857142857143) - c4 = convert(T2, 0.8571428571428571) - c5 = convert(T2, 0.276393202250021) - c6 = convert(T2, 0.7236067977499789) - c7 = convert(T2, 1.0) - - Alshina6ConstantCache(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, - a64, a65, a71, a72, a73, a74, a75, a76, - b1, b5, b6, b7, c2, c3, c4, c5, c6, c7) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/src/split_perform_step.jl b/lib/OrdinaryDiffEqLowOrderRK/src/split_perform_step.jl deleted file mode 100644 index aaa9a13783..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/src/split_perform_step.jl +++ /dev/null @@ -1,50 +0,0 @@ -function initialize!(integrator, cache::SplitEulerConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f.f1(integrator.uprev, integrator.p, integrator.t) + - integrator.f.f2(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - integrator.stats.nf2 += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -@muladd function perform_step!(integrator, cache::SplitEulerConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - u = @.. broadcast=false uprev+dt * integrator.fsalfirst - integrator.fsallast = f.f1(u, p, t + dt) + f.f2(u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 - integrator.stats.nf2 += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -function initialize!(integrator, cache::SplitEulerCache) - integrator.kshortsize = 2 - @unpack k, fsalfirst = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = k - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f.f1(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.f.f2(cache.tmp, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 - integrator.stats.nf2 += 1 - integrator.fsalfirst .+= cache.tmp -end - -@muladd function perform_step!(integrator, cache::SplitEulerCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @.. broadcast=false u=uprev + dt * integrator.fsalfirst - f.f1(integrator.fsallast, u, p, t + dt) # For the interpolation, needs k at the updated point - f.f2(cache.tmp, u, p, t + dt) # For the interpolation, needs k at the updated point - integrator.stats.nf2 += 1 - integrator.stats.nf += 1 - integrator.fsallast .+= cache.tmp -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/test/owrenzen_tests.jl b/lib/OrdinaryDiffEqLowOrderRK/test/owrenzen_tests.jl deleted file mode 100644 index 96b6cb57d7..0000000000 --- a/lib/OrdinaryDiffEqLowOrderRK/test/owrenzen_tests.jl +++ /dev/null @@ -1,43 +0,0 @@ -using OrdinaryDiffEq, DiffEqDevTools, DiffEqBase, Test, Random -import ODEProblemLibrary: prob_ode_2Dlinear, prob_ode_linear - -Random.seed!(100) -## Convergence Testing -dts = (1 / 2) .^ (7:-1:4) -testTol = 0.2 - -prob = prob_ode_linear -sol = solve(prob, OwrenZen3()) -@test length(sol) < 20 -sol = solve(prob, OwrenZen4()) -@test length(sol) < 20 -sol = solve(prob, OwrenZen5()) -@test length(sol) < 20 - -sim = test_convergence(dts, prob, OwrenZen3(), dense_errors = true) -@test sim.𝒪est[:final]≈3 atol=testTol -@test sim.𝒪est[:L2]≈3 atol=testTol -sim = test_convergence(dts, prob, OwrenZen4(), dense_errors = true) -@test sim.𝒪est[:final]≈4 atol=testTol -@test sim.𝒪est[:L2]≈4 atol=testTol -sim = test_convergence(dts, prob, OwrenZen5(), dense_errors = true) -@test sim.𝒪est[:final]≈5 atol=testTol -@test sim.𝒪est[:L2]≈5 atol=testTol - -prob = prob_ode_2Dlinear -sol = solve(prob, OwrenZen3()) -@test length(sol) < 20 -sol = solve(prob, OwrenZen4()) -@test length(sol) < 20 -sol = solve(prob, OwrenZen5()) -@test length(sol) < 20 - -sim = test_convergence(dts, prob, OwrenZen3(), dense_errors = true) -@test sim.𝒪est[:final]≈3 atol=testTol -@test sim.𝒪est[:L2]≈3 atol=testTol -sim = test_convergence(dts, prob, OwrenZen4(), dense_errors = true) -@test sim.𝒪est[:final]≈4 atol=testTol -@test sim.𝒪est[:L2]≈4 atol=testTol -sim = test_convergence(dts, prob, OwrenZen5(), dense_errors = true) -@test sim.𝒪est[:final]≈5 atol=testTol -@test sim.𝒪est[:L2]≈5 atol=testTol \ No newline at end of file diff --git a/lib/OrdinaryDiffEqLowOrderRK/test/runtests.jl b/lib/OrdinaryDiffEqLowOrderRK/test/runtests.jl deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lib/OrdinaryDiffEqRosenbrock/Project.toml b/lib/OrdinaryDiffEqRosenbrock/Project.toml deleted file mode 100644 index 422bbff248..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/Project.toml +++ /dev/null @@ -1,20 +0,0 @@ -name = "OrdinaryDiffEqRosenbrock" -uuid = "849cf443-90a5-45fe-9245-010b279924ce" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[compat] -julia = "1.10" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl deleted file mode 100644 index 73c272d63e..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl +++ /dev/null @@ -1,31 +0,0 @@ -module OrdinaryDiffEqRosenbrock - -import OrdinaryDiffEq: OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, - OrdinaryDiffEqRosenbrockAlgorithm, rosenbrock_docstring, - rosenbrock_wanner_docstring, - OrdinaryDiffEqMutableCache, alg_order, alg_adaptive_order, - OrdinaryDiffEqAlgorithm, - OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqAdaptiveAlgorithm -using DiffEqBase, MuladdMacro - -include("generic_rosenbrock.jl") -include("algorithms.jl") -include("alg_utils.jl") -include("rosenbrock_tableaus.jl") -include("rosenbrock_caches.jl") -include("integrator_interface.jl") -include("integrator_utils.jl") -include("interp_func.jl") -include("stiff_addsteps.jl") -include("rosenbrock_interpolants.jl") -include("rosenbrock_tableaus.jl") - -export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A, - Ros4LStab, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2, - Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, - RosenbrockW6S4OS, ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, - ROS3PRL2, ROK4a, - ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 - -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl b/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl deleted file mode 100644 index 7bd9bcce2d..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl +++ /dev/null @@ -1,68 +0,0 @@ -alg_order(alg::ROS2) = 2 -alg_order(alg::ROS2PR) = 2 -alg_order(alg::ROS2S) = 2 -alg_order(alg::ROS3) = 3 -alg_order(alg::ROS3PR) = 3 -alg_order(alg::Scholz4_7) = 3 -alg_order(alg::Rosenbrock23) = 2 -alg_order(alg::Rodas23W) = 3 -alg_order(alg::Rosenbrock32) = 3 -alg_order(alg::ROS3P) = 3 -alg_order(alg::Rodas3) = 3 -alg_order(alg::Rodas3P) = 3 -alg_order(alg::ROS34PW1a) = 3 -alg_order(alg::ROS34PW1b) = 3 -alg_order(alg::ROS34PW2) = 3 -alg_order(alg::ROS34PW3) = 4 -alg_order(alg::ROS34PRw) = 3 -alg_order(alg::ROS3PRL) = 3 -alg_order(alg::ROS3PRL2) = 3 -alg_order(alg::ROK4a) = 4 -alg_order(alg::RosShamp4) = 4 -alg_order(alg::Veldd4) = 4 -alg_order(alg::Velds4) = 4 -alg_order(alg::GRK4T) = 4 -alg_order(alg::GRK4A) = 4 -alg_order(alg::Ros4LStab) = 4 -alg_order(alg::RosenbrockW6S4OS) = 4 -alg_order(alg::Rodas4) = 4 -alg_order(alg::Rodas42) = 4 -alg_order(alg::Rodas4P) = 4 -alg_order(alg::Rodas4P2) = 4 -alg_order(alg::Rodas5) = 5 -alg_order(alg::Rodas5P) = 5 -alg_order(alg::Rodas5Pr) = 5 -alg_order(alg::Rodas5Pe) = 5 - -isfsal(alg::Rodas3P) = false -isfsal(alg::Rodas23W) = false -isfsal(alg::Rodas5) = false -isfsal(alg::Rodas5P) = false -isfsal(alg::Rodas5Pr) = false -isfsal(alg::Rodas5Pe) = false -isfsal(alg::Rodas4) = false -isfsal(alg::Rodas42) = false -isfsal(alg::Rodas4P) = false -isfsal(alg::Rodas4P2) = false - -isWmethod(alg::Rosenbrock23) = true -isWmethod(alg::Rosenbrock32) = true -isWmethod(alg::Rodas23W) = true -isWmethod(alg::ROS2S) = true -isWmethod(alg::ROS34PW1a) = true -isWmethod(alg::ROS34PW1b) = true -isWmethod(alg::ROS34PW2) = true -isWmethod(alg::ROS34PW3) = true -isWmethod(alg::ROS34PRw) = true -isWmethod(alg::ROK4a) = true -isWmethod(alg::RosenbrockW6S4OS) = true - -alg_adaptive_order(alg::Rosenbrock23) = 3 -alg_adaptive_order(alg::Rosenbrock32) = 2 - -is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true - -function is_mass_matrix_alg(alg::CompositeAlgorithm{ - <:Any, <:Tuple{Tsit5, Rosenbrock23, Rodas5P, FBDF, FBDF}}) - true -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl b/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl deleted file mode 100644 index 88f7520646..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl +++ /dev/null @@ -1,208 +0,0 @@ -################################################################################ - -# Rosenbrock Methods - -#= -#### Rosenbrock23, Rosenbrock32, ode23s, ModifiedRosenbrockIntegrator - -- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of -Scientific Computing, 18 (1), pp. 1-22. - -#### ROS2 - -- J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems - https://doi.org/10.1137/S1064827597326651 - -#### ROS3P - -- Lang, J. & Verwer, ROS3P—An Accurate Third-Order Rosenbrock Solver Designed for - Parabolic Problems J. BIT Numerical Mathematics (2001) 41: 731. doi:10.1023/A:1021900219772 - -#### ROS3, Rodas3, Ros4LStab, Rodas4, Rodas42 - -- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and - differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) - -#### ROS2PR, ROS2S, ROS3PR, Scholz4_7 --Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 - -#### RosShamp4 - -- L. F. Shampine, Implementation of Rosenbrock Methods, ACM Transactions on - Mathematical Software (TOMS), 8: 2, 93-113. doi:10.1145/355993.355994 - -#### Veldd4, Velds4 - -- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. - doi:10.1007/BF02243574 - -#### GRK4T, GRK4A - -- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control - for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 - -#### Rodas23W, Rodas3P - -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate for dense output and Julia implementation, - in progress - -#### Rodas4P - -- Steinebach G. Order-reduction of ROW-methods for DAEs and method of lines - applications. Preprint-Nr. 1741, FB Mathematik, TH Darmstadt; 1995. - -#### Rodas4P2 -- Steinebach G. (2020) Improvement of Rosenbrock-Wanner Method RODASP. - In: Reis T., Grundel S., Schoeps S. (eds) Progress in Differential-Algebraic Equations II. - Differential-Algebraic Equations Forum. Springer, Cham. https://doi.org/10.1007/978-3-030-53905-4_6 - -#### Rodas5 -- Di Marzo G. RODAS5(4) – Méthodes de Rosenbrock d’ordre 5(4) adaptées aux problemes -différentiels-algébriques. MSc mathematics thesis, Faculty of Science, -University of Geneva, Switzerland. - -#### ROS34PRw --Joachim Rang, Improved traditional Rosenbrock–Wanner methods for stiff ODEs and DAEs, - Journal of Computational and Applied Mathematics, - https://doi.org/10.1016/j.cam.2015.03.010 - -#### ROS3PRL, ROS3PRL2 --Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 - -#### ROK4a -- Tranquilli, Paul and Sandu, Adrian (2014): - Rosenbrock--Krylov Methods for Large Systems of Differential Equations - https://doi.org/10.1137/130923336 - -#### Rodas5P -- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks within the Julia Differential Equations package. - In: BIT Numerical Mathematics, 63(2), 2023 - - #### Rodas23W, Rodas3P, Rodas5Pe, Rodas5Pr -- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - - Preprint 2024 - https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf - -=# - -for Alg in [ - :ROS2, - :ROS2PR, - :ROS2S, - :ROS3, - :ROS3PR, - :Scholz4_7, - :ROS34PW1a, - :ROS34PW1b, - :ROS34PW2, - :ROS34PW3, - :ROS34PRw, - :ROS3PRL, - :ROS3PRL2, - :ROK4a, - :RosShamp4, - :Veldd4, - :Velds4, - :GRK4T, - :GRK4A, - :Ros4LStab] - @eval begin - struct $Alg{CS, AD, F, P, FDT, ST, CJ} <: - OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - end - function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = nothing, precs = DEFAULT_PRECS) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - precs) - end - end - - @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 -end - -# for Rosenbrock methods with step_limiter -for Alg in [ - :Rosenbrock23, - :Rosenbrock32, - :ROS3P, - :Rodas3, - :Rodas23W, - :Rodas3P, - :Rodas4, - :Rodas42, - :Rodas4P, - :Rodas4P2, - :Rodas5, - :Rodas5P, - :Rodas5Pe, - :Rodas5Pr] - @eval begin - struct $Alg{CS, AD, F, P, FDT, ST, CJ, StepLimiter, StageLimiter} <: - OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P - step_limiter!::StepLimiter - stage_limiter!::StageLimiter - end - function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = nothing, - precs = DEFAULT_PRECS, step_limiter! = trivial_limiter!, - stage_limiter! = trivial_limiter!) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!), - typeof(stage_limiter!)}(linsolve, precs, step_limiter!, - stage_limiter!) - end - end - - @eval TruncatedStacktraces.@truncate_stacktrace $Alg 1 2 -end -struct GeneralRosenbrock{CS, AD, F, ST, CJ, TabType} <: - OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, Val{:forward}, ST, CJ} - tableau::TabType - factorization::F -end - -function GeneralRosenbrock(; chunk_size = Val{0}(), autodiff = true, - standardtag = Val{true}(), concrete_jac = nothing, - factorization = lu!, tableau = ROSENBROCK_DEFAULT_TABLEAU) - GeneralRosenbrock{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(factorization), - _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(tableau)}(tableau, - factorization) -end - -@doc rosenbrock_wanner_docstring( - """ - A 4th order L-stable Rosenbrock-W method (fixed step only). - """, - "RosenbrockW6S4OS", - references = """ - https://doi.org/10.1016/j.cam.2009.09.017 - """) -struct RosenbrockW6S4OS{CS, AD, F, P, FDT, ST, CJ} <: - OrdinaryDiffEqRosenbrockAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - precs::P -end -function RosenbrockW6S4OS(; chunk_size = Val{0}(), autodiff = true, - standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:central}, - linsolve = nothing, - precs = DEFAULT_PRECS) - RosenbrockW6S4OS{_unwrap_val(chunk_size), - _unwrap_val(autodiff), typeof(linsolve), typeof(precs), diff_type, - _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, - precs) -end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl deleted file mode 100644 index 32330c27e1..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl +++ /dev/null @@ -1,1810 +0,0 @@ -#! format: off - -abstract type RosenbrockTableau{T,T2} end -struct RosenbrockFixedTableau{T,T2}<:RosenbrockTableau{T,T2} - a::Array{T,2} - C::Array{T,2} - b::Array{T,1} - gamma::T2 - d::Array{T,1} - c::Array{T2,1} -end - -struct RosenbrockAdaptiveTableau{T,T2}<:RosenbrockTableau{T,T2} - a::Array{T,2} - C::Array{T,2} - b::Array{T,1} - btilde::Array{T,1} - gamma::T2 - d::Array{T,1} - c::Array{T2,1} -end - -""" - @_bitarray2boolarray RosenbrockTableau(tab.a.!=0,...) - -Transform BitArray (in the form of `xs.!=0` ) into 1D-Array of Bools by -`[i for i in xs.!=0]` to satisfy the type constraint of RosenbrockTableau -""" -macro _bitarray2boolarray(expr) - args=[:([i for i in $arg]) for arg in expr.args[2:end]] - args[end-2]=:(tab.gamma!=0) - esc(:($(expr.args[1])($(args...)))) -end - -""" - _masktab(tab) - -Convert normal tableau into a dummy tableau consisting of Bools. We use dummy tableaus -where we only care about whether values in the tableau are zeros. -""" -_masktab(tab::RosenbrockFixedTableau)=@_bitarray2boolarray RosenbrockFixedTableau(tab.a.!=0,tab.C.!=0,tab.b.!=0,tab.gamma!=0,tab.d.!=0,tab.c.!=0) -_masktab(tab::RosenbrockAdaptiveTableau)=@_bitarray2boolarray RosenbrockAdaptiveTableau(tab.a.!=0,tab.C.!=0,tab.b.!=0,tab.btilde.!=0,tab.gamma!=0,tab.d.!=0,tab.c.!=0) - - -""" - _common_nonzero_vals(tab::RosenbrockTableau) - -Return the common nonzero symbols in the tableau. Typical return value: -`[[:a21,:a31,:a32],[:C21,:C31,:C32],[:b1,:b2,:b3],:gamma,[:d1,:d2,:d3],[:c1,:c2,:c3]]` -""" -function _common_nonzero_vals(tab::RosenbrockTableau) - nzvals=[] - push!(nzvals,[Symbol(:a,ind[1],ind[2]) for ind in findall(!iszero,tab.a)]) - push!(nzvals,[Symbol(:C,ind[1],ind[2]) for ind in findall(!iszero,tab.C)]) - push!(nzvals,[Symbol(:b,ind) for ind in findall(!iszero,tab.b)]) - push!(nzvals,:gamma) - push!(nzvals,[Symbol(:d,ind) for ind in findall(!iszero,tab.d)]) - push!(nzvals,[Symbol(:c,ind) for ind in findall(!iszero,tab.c)]) - nzvals -end - -""" - _nonzero_vals(tab::RosenbrockFixedTableau) - -Return all the nonzero symbols in the tableau. Typical return value: -`[:a21,:a31,:a32,:C21,:C31,:C32,:b1,:b2,:b3,:gamma,:d1,:d2,:d3,:c1,:c2,:c3]` -""" -function _nonzero_vals(tab::RosenbrockFixedTableau) - nzvals=_common_nonzero_vals(tab) - vcat(nzvals...) -end - -""" - _nonzero_vals(tab::RosenbrockAdaptiveTableau) - -Typical return value: -`[:a21,:a31,:a32,:C21,:C31,:C32,:b1,:b2,:b3,:btilde1,:btilde2,:btilde3,:gamma,:d1,:d2,:d3,:c1,:c2,:c3]` -""" -function _nonzero_vals(tab::RosenbrockAdaptiveTableau) - nzvals=_common_nonzero_vals(tab) - push!(nzvals,[Symbol(:btilde,ind) for ind in findall(!iszero,tab.btilde)]) - vcat(nzvals...) -end - -""" - _push_assigns!(valexprs,inds,name,type) - -Insert a series of field statements like `[:(c2::T2),:(c3::T2)]` into the array `valexprs`. - -# Arguments -- `valexpr::Array{Expr,1}`: the array to be inserted -- `inds`: an iterator that gives indices -- `name::Symbol`: the prefix name of the values -- `type::Symbol`: type in the statements -""" -function _push_assigns!(valexprs,inds,name,type::Symbol) - for ind in inds - push!(valexprs,:($(Symbol(name,"$(Tuple(ind)...)"))::$type)) - end -end - -""" - gen_tableau_struct(tab::RosenbrockTableau,tabstructname::Symbol) - -Generate the tableau struct expression from a given tableau emulating those in -`tableaus/rosenbrock_tableaus.jl`. The statements of `aij`,`Cij` and `ci` are generated -according to the nonzero values of `tab.a`,`tab.C` and `tab.c` while others are generated -from their indices. One may choose to pass in a dummy tableau with type `<:RosenbrockTalbeau{Bool,Bool}` -to fully control the tableau struct. -""" -function gen_tableau_struct(tab::RosenbrockTableau,tabstructname::Symbol) - valexprs=Array{Expr,1}() - _push_assigns!(valexprs,findall(!iszero,tab.a),:a,:T) - _push_assigns!(valexprs,findall(!iszero,tab.C),:C,:T) - _push_assigns!(valexprs,eachindex(tab.b),:b,:T) - if typeof(tab)<:RosenbrockAdaptiveTableau - _push_assigns!(valexprs,eachindex(tab.btilde),:btilde,:T) - end - push!(valexprs,:(gamma::T2)) - _push_assigns!(valexprs,eachindex(tab.d),:d,:T) - _push_assigns!(valexprs,findall(!iszero,tab.c),:c,:T2) - quote struct $tabstructname{T,T2} - $(valexprs...) - end - end -end - -""" - gen_tableau(tab::RosenbrockTableau,tabstructexpr::Expr,tabname::Symbol) - -Generate the tableau function expression emulating those in `tableaus/rosenbrock_tableaus.jl`. -It takes in the tableau struct expression (generated by gen_tableau_struct(...) or written by hand) -to make sure the actual values of the tableau are organized in the right order. -""" -function gen_tableau(tab::RosenbrockTableau,tabstructexpr::Expr,tabname::Symbol) - @capture(tabstructexpr, struct T_ fields__ end) || error("incorrect tableau expression") - tabstructname = namify(T) - valsym2tabdict=Dict("a"=>tab.a,"C"=>tab.C,"gamma"=>tab.gamma,"c"=>tab.c,"d"=>tab.d,"b"=>tab.b) - if typeof(tab)<:RosenbrockAdaptiveTableau - valsym2tabdict["btilde"]=tab.btilde - end - pattern=r"^([a-zA-Z]+)([1-9]{0,2})$" - assignexprs = Expr[] - valsyms = Symbol[] - for field in fields - if @capture(field, valsym_Symbol::valtype_) - push!(valsyms, valsym) - m = match(pattern, String(valsym)) - val = valsym2tabdict[m[1]][(parse(Int, i) for i in m[2])...] - push!(assignexprs, :($valsym = convert($valtype, $val))) - end - end - quote function $tabname(T, T2) - $(assignexprs...) - $tabstructname($(valsyms...)) - end - end -end - -""" - gen_cache_struct(tab::RosenbrockTableau,cachename::Symbol,constcachename::Symbol) - -Generate cache struct expression emulating those in `caches/rosenbrock_caches.jl`. -The length of k1,k2,... in the mutable cache struct is determined by the length of `tab.b` -because in the end of Rosenbrock's method, we have: `y_{n+1}=y_n+ki*bi`. -""" -function gen_cache_struct(tab::RosenbrockTableau,cachename::Symbol,constcachename::Symbol) - kstype=[:($(Symbol(:k,i))::rateType) for i in 1:length(tab.b)] - constcacheexpr=quote struct $constcachename{TF,UF,Tab,JType,WType,F} <: OrdinaryDiffEqConstantCache - tf::TF - uf::UF - tab::Tab - J::JType - W::WType - linsolve::F - end - end - cacheexpr=quote - @cache mutable struct $cachename{uType,rateType,uNoUnitsType,JType,WType,TabType,TFType,UFType,F,JCType,GCType} <: RosenbrockMutableCache - u::uType - uprev::uType - du::rateType - du1::rateType - du2::rateType - $(kstype...) - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - end - end - constcacheexpr,cacheexpr -end - -""" - gen_algcache(cacheexpr::Expr,constcachename::Symbol,algname::Symbol,tabname::Symbol) - -Generate expressions for `alg_cache(...)` emulating those in `caches/rosenbrock_caches.jl`. -""" -function gen_algcache(cacheexpr::Expr,constcachename::Symbol,algname::Symbol,tabname::Symbol) - @capture(cacheexpr, @cache mutable struct T_ fields__ end) || error("incorrect cache expression") - cachename = namify(T) - ksinit = Expr[] - valsyms = Symbol[] - for field in fields - if @capture(field, valsym_Symbol::valtype_) - push!(valsyms, valsym) - - if match(r"^k[1-9]+$", String(valsym)) !== nothing - push!(ksinit, :($valsym = zero(rate_prototype))) - end - end - end - - quote - function alg_cache(alg::$algname,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false}) - tf = TimeDerivativeWrapper(f,u,p) - uf = UDerivativeWrapper(f,t,p) - J,W = build_J_W(alg,u,uprev,p,t,dt,f,uEltypeNoUnits,Val(false)) - $constcachename(tf,uf,$tabname(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits)),J,W,nothing) - end - function alg_cache(alg::$algname,u,rate_prototype,uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits,uprev,uprev2,f,t,dt,reltol,p,calck,::Val{true}) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - $(ksinit...) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J,W = build_J_W(alg,u,uprev,p,t,dt,f,uEltypeNoUnits,Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - weight = similar(u, uEltypeNoUnits) - tab = $tabname(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f,uprev,p) - uf = UJacobianWrapper(f,t,p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W,_vec(linsolve_tmp); u0=_vec(tmp)) - linsolve = init(linprob,alg.linsolve,alias_A=true,alias_b=true, - Pl = LinearSolve.InvPreconditioner(Diagonal(_vec(weight))), - Pr = Diagonal(_vec(weight))) - grad_config = build_grad_config(alg,f,tf,du1,t) - jac_config = build_jac_config(alg,f,uf,du1,uprev,u,tmp,du2) - $cachename($(valsyms...)) - end - end -end - -""" - gen_initialize(cachename::Symbol,constcachename::Symbol) - -Generate expressions for `initialize!(...)` in `perform_step/rosenbrock_perform_step.jl`. -It only generates a default version of `initialize!` which support 3rd-order Hermite interpolation. -""" -function gen_initialize(cachename::Symbol,constcachename::Symbol) - quote - function initialize!(integrator, cache::$constcachename) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - end - - function initialize!(integrator, cache::$cachename) - integrator.kshortsize = 2 - @unpack fsalfirst,fsallast = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = fsallast - resize!(integrator.k, integrator.kshortsize) - integrator.k .= [fsalfirst,fsallast] - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - end - end -end - -""" - gen_constant_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) - -Generate non-inplace version of `perform_step!` expression emulating those in `perform_step/rosenbrock_perform_step.jl`. -The `perform_step!` function calculates `k1,k2,k3,...` defined by `(-W)ki=f(u+aij*kj,t+ci*dt)+di*dt*dT+Cij*kj*dt, i=1,2,...,n_normalstep` -and then gives the result by `y_{n+1}=y_n+ki*bi`. Terms with 0s (according to tabmask) are skipped in the expressions. -Special steps can be added before calculating `y_{n+1}`. The non-inplace `perform_step!` assumes the mass_matrix==I. -""" -function gen_constant_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) - unpacktabexpr=:(@unpack ()=cache.tab) - unpacktabexpr.args[3].args[1].args=_nonzero_vals(tabmask) - dtCijexprs=[:($(Symbol(:dtC,Cind[1],Cind[2]))=$(Symbol(:C,Cind[1],Cind[2]))/dt) for Cind in findall(!iszero,tabmask.C)] - dtdiexprs=[:($(Symbol(:dtd,dind))=dt*$(Symbol(:d,dind))) for dind in eachindex(tabmask.d)] - iterexprs=[] - for i in 1:n_normalstep - aijkj=[:($(Symbol(:a,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.a[i+1,:])] - Cijkj=[:($(Symbol(:dtC,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.C[i+1,:])] - push!(iterexprs, - quote - $(Symbol(:k,i)) = _reshape(W\-_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u=+(uprev,$(aijkj...)) - du = f(u, p, t+$(Symbol(:c,i+1))*dt) - integrator.stats.nf += 1 - if mass_matrix === I - linsolve_tmp=+(du,$(Symbol(:dtd,i+1))*dT,$(Cijkj...)) - else - linsolve_tmp=du+$(Symbol(:dtd,i+1))*dT+mass_matrix*(+($(Cijkj...))) - end - end) - end - push!(iterexprs,specialstepexpr) - n=length(tabmask.b) - biki=[:($(Symbol(:b,i))*$(Symbol(:k,i))) for i in 1:n] - push!(iterexprs, - quote - $(Symbol(:k,n))=_reshape(W\-_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u=+(uprev,$(biki...)) - end) - - adaptiveexpr=[] - if typeof(tabmask)<:RosenbrockAdaptiveTableau - btildeiki=[:($(Symbol(:btilde,i))*$(Symbol(:k,i))) for i in findall(!iszero,tabmask.btilde)] - push!(adaptiveexpr,quote - if integrator.opts.adaptive - utilde = +($(btildeiki...)) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol,integrator.opts.internalnorm,t) - integrator.EEst = integrator.opts.internalnorm(atmp,t) - end - end) - end - quote - @muladd function perform_step!(integrator, cache::$cachename, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - @unpack tf,uf = cache - $unpacktabexpr - - $(dtCijexprs...) - $(dtdiexprs...) - dtgamma = dt*gamma - - mass_matrix = integrator.f.mass_matrix - - # Time derivative - tf.u = uprev - dT = ForwardDiff.derivative(tf, t) - - W = calc_W(integrator, cache, dtgamma, repeat_step, true) - linsolve_tmp = integrator.fsalfirst + dtd1*dT #calc_rosenbrock_differentiation! - - $(iterexprs...) - - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - - $(adaptiveexpr...) - end - end - -end - -""" - gen_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) - -Generate inplace version of `perform_step!` expression emulating those in `perform_step/rosenbrock_perform_step.jl`. -The inplace `perform_step!` produces the same result as the non-inplace version except that it treats the mass_matrix appropriately. -""" -function gen_perform_step(tabmask::RosenbrockTableau{Bool,Bool},cachename::Symbol,n_normalstep::Int,specialstepexpr=:nothing) - unpacktabexpr=:(@unpack ()=cache.tab) - unpacktabexpr.args[3].args[1].args=_nonzero_vals(tabmask) - dtCij=[:($(Symbol(:dtC,"$(Cind[1])$(Cind[2])"))=$(Symbol(:C,"$(Cind[1])$(Cind[2])"))/dt) for Cind in findall(!iszero,tabmask.C)] - dtdi=[:($(Symbol(:dtd,dind[1]))=dt*$(Symbol(:d,dind[1]))) for dind in eachindex(tabmask.d)] - iterexprs=[] - for i in 1:n_normalstep - ki=Symbol(:k,i) - dtdj=Symbol(:dtd,i+1) - aijkj=[:($(Symbol(:a,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.a[i+1,:])] - dtCijkj=[:($(Symbol(:dtC,i+1,j))*$(Symbol(:k,j))) for j in findall(!iszero,tabmask.C[i+1,:])] - repeatstepexpr=[] - if i==1 - repeatstepexpr=[:(!repeat_step)] - end - push!(iterexprs,quote - - if $(i==1) - # Must be a part of the first linsolve for preconditioner step - linres = dolinsolve(integrator, linsolve; A = !repeat_step ? W : nothing, b = _vec(linsolve_tmp)) - else - linres = dolinsolve(integrator, linsolve; b = _vec(linsolve_tmp)) - end - - linsolve = linres.cache - vecu = _vec(linres.u) - vecki = _vec($ki) - - @.. broadcast=false vecki = -vecu - - integrator.stats.nsolve += 1 - @.. broadcast=false u = +(uprev,$(aijkj...)) - f( du, u, p, t+$(Symbol(:c,i+1))*dt) - integrator.stats.nf += 1 - if mass_matrix === I - @.. broadcast=false linsolve_tmp = +(du,$dtdj*dT,$(dtCijkj...)) - else - @.. broadcast=false du1 = +($(dtCijkj...)) - mul!(_vec(du2),mass_matrix,_vec(du1)) - @.. broadcast=false linsolve_tmp = du + $dtdj*dT + du2 - end - end) - end - push!(iterexprs,specialstepexpr) - n=length(tabmask.b) - ks=[Symbol(:k,i) for i in 1:n] - klast=Symbol(:k,n) - biki=[:($(Symbol(:b,i))*$(Symbol(:k,i))) for i in 1:n] - push!(iterexprs,quote - - linres = dolinsolve(integrator, linsolve; b = _vec(linsolve_tmp)) - linsolve = linres.cache - vecu = _vec(linres.u) - vecklast = _vec($klast) - @.. broadcast=false vecklast = -vecu - - integrator.stats.nsolve += 1 - @.. broadcast=false u = +(uprev,$(biki...)) - end) - - adaptiveexpr=[] - if typeof(tabmask)<:RosenbrockAdaptiveTableau - btildeiki=[:($(Symbol(:btilde,i))*$(Symbol(:k,i))) for i in findall(!iszero,tabmask.btilde)] - push!(adaptiveexpr,quote - utilde=du - if integrator.opts.adaptive - @.. broadcast=false utilde = +($(btildeiki...)) - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol,integrator.opts.internalnorm,t) - integrator.EEst = integrator.opts.internalnorm(atmp,t) - end - end) - end - quote - @muladd function perform_step!(integrator, cache::$cachename, repeat_step=false) - @unpack t,dt,uprev,u,f,p = integrator - @unpack du,du1,du2,fsallast,dT,J,W,uf,tf,$(ks...),linsolve_tmp,jac_config,atmp,weight = cache - $unpacktabexpr - - # Assignments - sizeu = size(u) - uidx = eachindex(integrator.uprev) - mass_matrix = integrator.f.mass_matrix - - # Precalculations - $(dtCij...) - $(dtdi...) - dtgamma = dt*gamma - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) - - calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) - - linsolve = cache.linsolve - - $(iterexprs...) - - f( fsallast, u, p, t + dt) - integrator.stats.nf += 1 - - $(adaptiveexpr...) - end - end -end - -""" - RosenbrockW6S4OSTableau() - -Rahunanthan, A., & Stanescu, D. (2010). High-order W-methods. -Journal of computational and applied mathematics, 233(8), 1798-1811. -""" -function RosenbrockW6S4OSTableau() - a=[0 0 0 0 0; - 0.5812383407115008 0 0 0 0; - 0.9039624413714670 1.8615191555345010 0 0 0; - 2.0765797196750000 0.1884255381414796 1.8701589674910320 0 0; - 4.4355506384843120 5.4571817986101890 4.6163507880689300 3.1181119524023610 0; - 10.791701698483260 -10.05691522584131 14.995644854284190 5.2743399543909430 1.4297308712611900] - C=[0 0 0 0 0; - -2.661294105131369 0 0 0 0; - -3.128450202373838 0.0000000000000000 0 0 0; - -6.920335474535658 -1.202675288266817 -9.733561811413620 0 0; - -28.09530629102695 20.371262954793770 -41.04375275302869 -19.66373175620895 0; - 9.7998186780974000 11.935792886603180 3.6738749290132010 14.807828541095500 0.8318583998690680] - b=[6.4562170746532350,-4.853141317768053,9.7653183340692600,2.0810841772787230,0.6603936866352417,0.6000000000000000] - gamma=0.2500000000000000 - d=[0.2500000000000000,0.0836691184292894,0.0544718623516351,-0.3402289722355864,0.0337651588339529,-0.0903074267618540] - c=[0 ,0.1453095851778752,0.3817422770256738,0.6367813704374599,0.7560744496323561,0.9271047239875670] - RosenbrockFixedTableau(a,C,b,gamma,d,c) -end - -""" - @RosenbrockW6S4OS(part) - -Generate code for the RosenbrockW6S4OS method. -`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. -`@RosenbrockW6S4OS(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. -`@RosenbrockW6S4OS(:cache)` should be placed in `caches/rosenbrock_caches.jl`. -`@RosenbrockW6S4OS(:init)` and `@RosenbrockW6S4OS(:performstep)` should be -placed in `perform_step/rosenbrock_perform_step.jl`. -""" -macro RosenbrockW6S4OS(part) - tab=RosenbrockW6S4OSTableau() - tabmask=_masktab(tab) - algname=:RosenbrockW6S4OS - tabname=:RosenbrockW6S4OSTableau - tabstructname=:RosenbrockW6STableau - cachename=:RosenbrockW6SCache - constcachename=:RosenbrockW6SConstantCache - n_normalstep=length(tab.b)-1 - if part.value==:tableau - #println("Generating const cache") - tabstructexpr=gen_tableau_struct(tabmask,tabstructname) - tabexpr=gen_tableau(tab,tabstructexpr,tabname) - return esc(quote $([tabstructexpr,tabexpr]...) end) - elseif part.value==:cache - #println("Generating cache") - constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) - algcacheexpr=gen_algcache(cacheexpr,constcachename,algname,tabname) - return esc(quote $([constcacheexpr,cacheexpr,algcacheexpr]...) end) - elseif part.value==:init - #println("Generating initialize") - return esc(gen_initialize(cachename,constcachename)) - elseif part.value==:performstep - #println("Generating perform_step") - constperformstepexpr=gen_constant_perform_step(tabmask,constcachename,n_normalstep) - performstepexpr=gen_perform_step(tabmask,cachename,n_normalstep) - return esc(quote $([constperformstepexpr,performstepexpr]...) end) - else - throw(ArgumentError("Unknown parameter!")) - nothing - end -end - -""" - Ros4dummyTableau() - -Generate a dummy tableau for ROS4 methods. It can be considered as performing elementwise OR to the masks -of those specific tableaus: `Ros4dummyTableau()==_masktab(RosShamp4Tableau()) OR _masktab(Veldd4Tableau()) OR ...` -ROS4 methods have the property of a4j==a3j so a is a 3*3 matrix instead of a 4*4 matrix and c is a 1*3 vector instead of a 1*4 vector. -""" -function Ros4dummyTableau()#create a tabmask for all ROS4 methods where false->0,true->non-0 - a=[false false false; - true false false; - true true false] - C=[false false false false; - true false false false; - true true false false; - true true true false] - b=[true,true,true,true] - btilde=[true,true,true,true] - gamma=true - c=[false,true,true] - d=[true,true,true,true] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - RosShamp4Tableau() - -L. F. Shampine, Implementation of Rosenbrock Methods, -ACM Transactions on Mathematical Software (TOMS), 8: 2, 93-113. -doi:10.1145/355993.355994 -""" -function RosShamp4Tableau() - a=[0 0 0; - 2 0 0; - 48//25 6//25 0] - C=[ 0 0 0 0; - -8 0 0 0; - 372//25 12//5 0 0; - -112//125 -54//125 -2//5 0] - b=[19//9,1//2,25//108,125//108] - btilde=[17//54,7//36,0,125//108] - gamma=1//2 - c=[0,1,3//5] - d=[1//2,-3//2,242//100,116//1000]#2.42,0.116 - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - Veldd4Tableau() - -van Veldhuizen, D-stability and Kaps-Rentrop-methods, -M. Computing (1984) 32: 229. doi:10.1007/BF02243574 -""" -function Veldd4Tableau() - a=[0 0 0; - 2 0 0; - 4.812234362695436 4.578146956747842 0] - C=[ 0 0 0 0; - -5.333333333333331 0 0 0; - 6.100529678848254 1.804736797378427 0 0; - -2.540515456634749 -9.443746328915205 -1.988471753215993 0] - b=[4.289339254654537,5.036098482851414,0.6085736420673917,1.355958941201148] - btilde=[2.175672787531755,2.950911222575741,-0.7859744544887430,-1.355958941201148] - gamma=0.2257081148225682 - c=[0,0.4514162296451364,0.8755928946018455] - d=[0.2257081148225682,-0.04599403502680582,0.5177590504944076,-0.03805623938054428] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - Velds4Tableau() - -van Veldhuizen, D-stability and Kaps-Rentrop-methods, -M. Computing (1984) 32: 229. doi:10.1007/BF02243574 -""" -function Velds4Tableau() - a=[0 0 0; - 2 0 0; - 7//4 1//4 0] - C=[ 0 0 0 0; - -8 0 0 0; - -8 -1 0 0; - 1//2 -1//2 2 0] - b=[4//3,2//3,-4//3,4//3] - btilde=[-1//3,-1//3,0,-4//3] - gamma=1//2 - c=[0,1,1//2] - d=[1//2,-3//2,-3//4,1//4] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - GRK4TTableau() - -Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four -with stepsize control for stiff ordinary differential equations. -P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 -""" -function GRK4TTableau() - a=[0 0 0; - 2 0 0; - 4.524708207373116 4.163528788597648 0] - C=[ 0 0 0 0; - -5.071675338776316 0 0 0; - 6.020152728650786 0.1597506846727117 0 0; - -1.856343618686113 -8.505380858179826 -2.084075136023187 0] - b=[3.957503746640777,4.624892388363313,0.6174772638750108,1.282612945269037] - btilde=[2.302155402932996,3.073634485392623,-0.8732808018045032,-1.282612945269037] - gamma=0.231 - c=[0,0.462,0.8802083333333334] - d=[0.2310000000000000,-0.03962966775244303,0.5507789395789127,-0.05535098457052764] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - GRK4ATableau() - -Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four -with stepsize control for stiff ordinary differential equations. -P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 -""" -function GRK4ATableau() - a=[0 0 0; - 1.108860759493671 0 0; - 2.377085261983360 0.1850114988899692 0] - C=[ 0 0 0 0; - -4.920188402397641 0 0 0; - 1.055588686048583 3.351817267668938 0 0; - 3.846869007049313 3.427109241268180 -2.162408848753263 0] - b=[1.845683240405840,0.1369796894360503,0.7129097783291559,0.6329113924050632] - btilde=[0.04831870177201765,-0.6471108651049505,0.2186876660500240,-0.6329113924050632] - gamma=0.395 - c=[0,0.438,0.87] - d=[0.395,-0.3726723954840920,0.06629196544571492,0.4340946962568634] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - Ros4LSTableau() - -E. Hairer, G. Wanner, Solving ordinary differential equations II, -stiff and differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) -""" -function Ros4LSTableau() - a=[0 0 0; - 2 0 0; - 1.867943637803922 0.2344449711399156 0] - C=[ 0 0 0 0; - -7.137615036412310 0 0 0; - 2.580708087951457 0.6515950076447975 0 0; - -2.137148994382534 -0.3214669691237626 -0.6949742501781779 0] - b=[2.255570073418735,0.2870493262186792,0.4353179431840180,1.093502252409163] - btilde=[-0.2815431932141155,-0.07276199124938920,-0.1082196201495311,-1.093502252409163] - gamma=0.5728200000000000 - c=[0,1.145640000000000,0.6552168638155900] - d=[0.5728200000000000,-1.769193891319233,0.7592633437920482,-0.1049021087100450] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - @Rosenbrock4(part) - -Generate code for the Rosenbrock4 methods: RosShamp4, Veldd4, Velds4, GRK4A, GRK4T, Ros4LStab. -`part` should be one of `:tableau`, `:cache`, `:performstep`. -`@Rosenbrock4(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. -`@Rosenbrock4(:cache)` should be placed in `caches/rosenbrock_caches.jl`. -`@Rosenbrock4(:performstep)` should be placed in `perform_step/rosenbrock_perform_step.jl`. -The `initialize!` function for Rosenbrock4 methods is already included in `rosenbrock_perform_step.jl`. -The special property of ROS4 methods that a4j==a3j requires a special step in `perform_step!` that -calculates `linsolve_tmp` from the previous `du` which reduces a function call. -""" -macro Rosenbrock4(part) - tabmask=Ros4dummyTableau()#_masktab(tab) - cachename=:Rosenbrock4Cache - constcachename=:Rosenbrock4ConstantCache - RosShamp4tabname=:RosShamp4Tableau - Veldd4tabname=:Veldd4Tableau - Velds4tabname=:Velds4Tableau - GRK4Ttabname=:GRK4TTableau - GRK4Atabname=:GRK4ATableau - Ros4LStabname=:Ros4LStabTableau - n_normalstep=2 #for the third step a4j=a3j which reduced one function call - if part.value==:tableau - #println("Generating tableau for Rosenbrock4") - tabstructexpr=gen_tableau_struct(tabmask,:Ros4Tableau) - tabexprs=Array{Expr,1}() - push!(tabexprs,tabstructexpr) - push!(tabexprs,gen_tableau(RosShamp4Tableau(),tabstructexpr,RosShamp4tabname)) - push!(tabexprs,gen_tableau(Veldd4Tableau(),tabstructexpr,Veldd4tabname)) - push!(tabexprs,gen_tableau(Velds4Tableau(),tabstructexpr,Velds4tabname)) - push!(tabexprs,gen_tableau(GRK4TTableau(),tabstructexpr,GRK4Ttabname)) - push!(tabexprs,gen_tableau(GRK4ATableau(),tabstructexpr,GRK4Atabname)) - push!(tabexprs,gen_tableau(Ros4LSTableau(),tabstructexpr,Ros4LStabname)) - return esc(quote $(tabexprs...) end) - elseif part.value==:cache - #println("Generating cache for Rosenbrock4") - constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) - cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:RosShamp4,RosShamp4tabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Veldd4,Veldd4tabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Velds4,Velds4tabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:GRK4T,GRK4Ttabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:GRK4A,GRK4Atabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Ros4LStab,Ros4LStabname)) - return esc(quote $(cacheexprs...) end) - elseif part.value==:performstep - #println("Generating perform_step for Rosenbrock4") - specialstepconst=quote - k3 = _reshape(W\-_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - #u = uprev + a31*k1 + a32*k2 #a4j=a3j - #du = f(u, p, t+c3*dt) #reduced function call - if mass_matrix === I - linsolve_tmp = du + dtd4*dT + dtC41*k1 + dtC42*k2 + dtC43*k3 - else - linsolve_tmp = du + dtd4*dT + mass_matrix * (dtC41*k1 + dtC42*k2 + dtC43*k3) - end - end - specialstep=quote - - linres = dolinsolve(integrator, linsolve; b = _vec(linsolve_tmp)) - linsolve = linres.cache - cache.linsolve = linsolve - vecu = _vec(linres.u) - veck3 = _vec(k3) - @.. broadcast=false veck3 = -vecu - - integrator.stats.nsolve += 1 - #@.. broadcast=false u = uprev + a31*k1 + a32*k2 #a4j=a3j - #f( du, u, p, t+c3*dt) #reduced function call - if mass_matrix === I - @.. broadcast=false linsolve_tmp = du + dtd4*dT + dtC41*k1 + dtC42*k2 + dtC43*k3 - else - @.. broadcast=false du1 = dtC41*k1 + dtC42*k2 + dtC43*k3 - mul!(du2,mass_matrix,du1) - @.. broadcast=false linsolve_tmp = du + dtd4*dT + du2 - end - end - constperformstepexpr=gen_constant_perform_step(tabmask,constcachename,n_normalstep,specialstepconst) - performstepexpr=gen_perform_step(tabmask,cachename,n_normalstep,specialstep) - return esc(quote $([constperformstepexpr,performstepexpr]...) end) - else - throw(ArgumentError("Unknown parameter!")) - nothing - end -end - -#ROS2, ROS23 and ROS34PW methods (Rang and Angermann, 2005) - -""" - Ros34dummyTableau() - -Generate a dummy tableau for ROS34W methods proposed by Rang and Angermann. This type of methods has 4 steps. -""" -function Ros34dummyTableau() - a=[false false false false; - true false false false; - true true false false; - true true true false] - C=[false false false false; - true false false false; - true true false false; - true true true false] - b=[true,true,true,true] - btilde=[true,true,true,true] - gamma=true - c=[false,true,true,true] - d=[true,true,true,true] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - Ros23dummyTableau() - -Generate a dummy tableau for ROS23 methods proposed by Rang. This type of methods has 3 steps. -""" -function Ros23dummyTableau() - a=[false false false; - true false false; - true true false] - C=[false false false; - true false false; - true true false;] - b=[true,true,true] - btilde=[true,true,true] - gamma=true - c=[false,true,true] - d=[true,true,true] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - Ros2dummyTableau() - -Generate a dummy tableau for ROS2 methods. This type of methods has 2 steps. -""" -function Ros2dummyTableau() - a=[false false; - true false] - C=[false false; - true false] - b=[true,true] - btilde=[true,true] - gamma=true - c=[false,true] - d=[true,true] - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - - -""" - _transformtab(Alpha,Gamma,B,Bhat) - -Transform the tableau from values in the paper into values used in OrdinaryDiffEq according to p112 in Hairer and Wanner. - -E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and -differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) -""" -function _transformtab(Alpha,Gamma,B,Bhat) - invGamma=inv(Gamma) - a=Alpha*invGamma - C=diagm(0=>diag(invGamma))-invGamma - b=[(transpose(B)*invGamma)...]# [2Darray...]=>1Darray - btilde=[(transpose(B-Bhat)*invGamma)...] - gamma=Gamma[1,1]#Gamma11==Gamma22==...==Gammass - d=[sum(Gamma,dims=2)...]#di=sum_j Gamma_ij - c=[sum(Alpha,dims=2)...]#ci=sum_j Alpha_ij - (a,C,b,btilde,d,c) -end - - - - -# 2 step ROS Methods -""" - ROS2Tableau() -2nd order stiffly accurate Rosenbrock method with 2 internal stages with (Rinf=0). -The embedded method is taken from Kinetic PreProcessor (KPP). -J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems -https://doi.org/10.1137/S1064827597326651 -""" -function ROS2Tableau() # 2nd order - gamma=1.7071067811865475 # 1+1/sqrt(2) - Alpha=[0 0; - 1. 0] - Gamma=[gamma 0; - -3.414213562373095 gamma] - B=[0.5, 0.5] - Bhat=[1, 0] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_wanner_docstring( -""" -An Order 2/3 L-Stable Rosenbrock-W method which is good for very stiff equations with oscillations at low tolerances. 2nd order stiff-aware interpolation. -""", -"Rosenbrock23", -references = """ -- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of -Scientific Computing, 18 (1), pp. 1-22. -""", -with_step_limiter = true) Rosenbrock23 - -@doc rosenbrock_wanner_docstring( -""" -An Order 3/2 A-Stable Rosenbrock-W method which is good for mildly stiff equations without oscillations at low tolerances. Note that this method is prone to instability in the presence of oscillations, so use with caution. 2nd order stiff-aware interpolation. -""", -"Rosenbrock32", -references = """ -- Shampine L.F. and Reichelt M., (1997) The MATLAB ODE Suite, SIAM Journal of -Scientific Computing, 18 (1), pp. 1-22. -""", -with_step_limiter = true) Rosenbrock32 - -@doc rosenbrock_docstring( -""" -3rd order A-stable and stiffly stable Rosenbrock method. Keeps high accuracy on discretizations of nonlinear parabolic PDEs. -""", -"ROS3P", -references = """ -- Lang, J. & Verwer, ROS3P—An Accurate Third-Order Rosenbrock Solver Designed for - Parabolic Problems J. BIT Numerical Mathematics (2001) 41: 731. doi:10.1023/A:1021900219772 -""", -with_step_limiter = true) ROS3P - -@doc rosenbrock_wanner_docstring( -""" -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. -""", -"Rodas23W", -references = """ -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate for dense output and Julia implementation, - In progress. -""", -with_step_limiter = true) Rodas23W - -@doc rosenbrock_wanner_docstring( -""" -A 4th order L-stable Rosenbrock-W method. -""", -"ROS34PW1a") ROS34PW1a - -@doc rosenbrock_wanner_docstring( -""" -A 4th order L-stable Rosenbrock-W method. -""", -"ROS34PW1b") ROS34PW1b - -@doc rosenbrock_wanner_docstring( -""" -A 4th order stiffy accurate Rosenbrock-W method for PDAEs. -""", -"ROS34PW2") ROS34PW2 - -@doc rosenbrock_wanner_docstring( -""" -A 4th order strongly A-stable (Rinf~0.63) Rosenbrock-W method. -""", -"ROS34PW3") ROS34PW3 - -@doc rosenbrock_docstring( -""" -An A-stable 4th order Rosenbrock method. -""", -"RosShamp4", -references = """ -- L. F. Shampine, Implementation of Rosenbrock Methods, ACM Transactions on - Mathematical Software (TOMS), 8: 2, 93-113. doi:10.1145/355993.355994 -""") RosShamp4 - -@doc rosenbrock_docstring( -""" -3rd order A-stable and stiffly stable Rosenbrock method. -""", -"Rodas3", -references = """ -- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks - within the Julia Differential Equations package. - In: BIT Numerical Mathematics, 63(2), 2023 -""", -with_step_limiter=true) Rodas3 - -@doc rosenbrock_docstring( -""" -3rd order A-stable and stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant -and additional error test for interpolation. Keeps accuracy on discretizations of linear parabolic PDEs. -""", -"Rodas3P", -references = """ -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate - for dense output and Julia implementation, - In progress. -""", -with_step_limiter=true) Rodas3P - -@doc rosenbrock_docstring( -""" -A 4th order L-stable Rosenbrock method. -""", -"Rodas4", -references = """ -- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and - differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) -""", -with_step_limiter=true) Rodas4 - -@doc rosenbrock_docstring( -""" -A 4th order A-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant -""", -"Ros4LStab", -references = """ -- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and - differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) -""", -with_step_limiter=true) Ros4LStab - - -@doc rosenbrock_docstring( -""" -A 4th order A-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant -""", -"Rodas42", -references = """ -- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and - differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) -""", -with_step_limiter=true) Rodas42 - -@doc rosenbrock_wanner_docstring( -""" -4th order A-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant. 4th order -on linear parabolic problems and 3rd order accurate on nonlinear parabolic problems (as opposed to -lower if not corrected). -""", -"Rodas4P", -references = """ -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate - for dense output and Julia implementation, - In progress. -""", -with_step_limiter=true) Rodas4P - -@doc rosenbrock_wanner_docstring( -""" -A 4th order L-stable stiffly stable Rosenbrock method with a stiff-aware 3rd order interpolant. 4th order -on linear parabolic problems and 3rd order accurate on nonlinear parabolic problems. It is an improvement -of Roadas4P and in case of inexact Jacobians a second order W method. -""", -"Rodas4P2", -references = """ -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate - for dense output and Julia implementation, - In progress. -""", -with_step_limiter=true) Rodas4P2 - -@doc rosenbrock_docstring( -""" -A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. -""", -"Rodas5", -references = """ -- Di Marzo G. RODAS5(4) – Méthodes de Rosenbrock d’ordre 5(4) adaptées aux problemes - différentiels-algébriques. MSc mathematics thesis, Faculty of Science, - University of Geneva, Switzerland. -""", -with_step_limiter=true) Rodas5 - -@doc rosenbrock_docstring( -""" -A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. -Has improved stability in the adaptive time stepping embedding. -""", -"Rodas5P", -references = """ -- Steinebach G. Construction of Rosenbrock–Wanner method Rodas5P and numerical benchmarks - within the Julia Differential Equations package. - In: BIT Numerical Mathematics, 63(2), 2023 -""", -with_step_limiter=true) Rodas5P - -@doc rosenbrock_docstring( -""" -A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. -Has improved stability in the adaptive time stepping embedding. -""", -"Rodas5Pr", -references = """ -- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - - Preprint 2024 - https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf -""", -with_step_limiter=true) Rodas5Pr - -@doc rosenbrock_docstring( -""" -A 5th order A-stable stiffly stable Rosenbrock method with a stiff-aware 4th order interpolant. -Has improved stability in the adaptive time stepping embedding. -""", -"Rodas5Pe", -references = """ -- Steinebach G. Rosenbrock methods within OrdinaryDiffEq.jl - Overview, recent developments and applications - - Preprint 2024 - https://github.com/hbrs-cse/RosenbrockMethods/blob/main/paper/JuliaPaper.pdf -""", -with_step_limiter=true) Rodas5Pe - -@doc rosenbrock_docstring( -""" -An efficient 4th order Rosenbrock method. -""", -"GRK4T", -references = """ -- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control - for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 -""", -with_step_limiter=true) GRK4T - -@doc rosenbrock_docstring( -""" -An A-stable 4th order Rosenbrock method. Essentially "anti-L-stable" but efficient. -""", -"GRK4A", -references = """ -- Kaps, P. & Rentrop, Generalized Runge-Kutta methods of order four with stepsize control - for stiff ordinary differential equations. P. Numer. Math. (1979) 33: 55. doi:10.1007/BF01396495 -""", -with_step_limiter=true) GRK4A - -@doc rosenbrock_docstring( -""" -A 4th order D-stable Rosenbrock method. -""", -"Veldd4", -references = """ -- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. - doi:10.1007/BF02243574 -""", -with_step_limiter=true) Veldd4 - -@doc rosenbrock_docstring( -""" -A 4th order A-stable Rosenbrock method. -""", -"Velds4", -references = """ -- van Veldhuizen, D-stability and Kaps-Rentrop-methods, M. Computing (1984) 32: 229. - doi:10.1007/BF02243574 -""", -with_step_limiter=true) Velds4 - -""" - @ROS2(part) - -Generate code for the 2 step ROS methods: ROS2 -`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. -`@ROS2(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. -`@ROS2(:cache)` should be placed in `caches/rosenbrock_caches.jl`. -`@ROS2(:init)` and `@ROS2(:performstep)` should be placed in -`perform_step/rosenbrock_perform_step.jl`. -""" -macro ROS2(part) - tabmask=Ros2dummyTableau() - cachename=:ROS2Cache - constcachename=:ROS2ConstantCache - ROS2tabname=:ROS2Tableau - n_normalstep=length(tabmask.b)-1 - if part.value==:tableau - tabstructexpr=gen_tableau_struct(tabmask,:Ros2Tableau) - tabexprs=Array{Expr,1}([tabstructexpr]) - push!(tabexprs,gen_tableau(ROS2Tableau(),tabstructexpr,ROS2tabname)) - return esc(quote $(tabexprs...) end) - elseif part.value==:cache - constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) - cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS2,ROS2tabname)) - return esc(quote $(cacheexprs...) end) - elseif part.value==:init - return esc(gen_initialize(cachename,constcachename)) - elseif part.value==:performstep - performstepexprs=Array{Expr,1}() - push!(performstepexprs,gen_constant_perform_step(tabmask,constcachename,n_normalstep)) - push!(performstepexprs,gen_perform_step(tabmask,cachename,n_normalstep)) - return esc(quote $(performstepexprs...) end) - else - throw(ArgumentError("Unknown parameter!")) - nothing - end -end - -@doc rosenbrock_docstring( -""" -A 2nd order L-stable Rosenbrock method with 2 internal stages. -""", -"ROS2", -references = """ -- J. G. Verwer et al. (1999): A second-order Rosenbrock method applied to photochemical dispersion problems - https://doi.org/10.1137/S1064827597326651 -""") ROS2 - -# 3 step ROS Methods -""" - ROS2PRTableau() - -2nd order stiffly accurate Rosenbrock method with 3 internal stages with (Rinf=0). -For problems with medium stiffness the convergence behaviour is very poor and it is recommended to use -[`ROS2S`](@ref) instead. - -Rang, Joachim (2014): The Prothero and Robinson example: -Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 -""" -function ROS2PRTableau() # 2nd order - gamma=2.28155493653962e-01 - Alpha=[0 0 0; - 1.00000000000000e+00 0 0; - 0.00000000000000e+00 1.0000000000000e+00 0] - Gamma=[gamma 0 0; - -2.28155493653962e-01 gamma 0; - 6.47798871261042e-01 -8.75954364915004e-01 gamma] - B=[6.47798871261042e-01,1.24045635084996e-01, 2.28155493653962e-01] - Bhat=[7.71844506346038e-01, 2.28155493653962e-01, 0.00000000000000e+00] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_docstring( -""" -2nd order stiffly accurate Rosenbrock method with 3 internal stages with (Rinf=0). -For problems with medium stiffness the convergence behaviour is very poor and it is recommended to use -[`ROS2S`](@ref) instead. -""", -"ROS2PR", -references = """ -- Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 -""") -ROS2PR - - - -""" - ROS2STableau() - -2nd order stiffly accurate Rosenbrock-Wanner W-method with 3 internal stages with B_PR consistent of order 2 with (Rinf=0). -More Information at https://doi.org/10.24355/dbbs.084-201408121139-0 - -Rang, Joachim (2014): The Prothero and Robinson example: -Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 -""" -function ROS2STableau() # 2nd order - gamma=2.92893218813452e-01 - Alpha=[0 0 0; - 5.85786437626905e-01 0 0; - 0.00000000000000e+00 1.0000000000000e+00 0] - Gamma=[gamma 0 0; - -5.85786437626905e-01 gamma 0; - 3.53553390593274e-01 -6.46446609406726e-01 gamma] - B=[3.53553390593274e-01,3.53553390593274e-01, 2.92893218813452e-01] - Bhat=[3.33333333333333e-01, 3.33333333333333e-01, 3.33333333333333e-01] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_wanner_docstring( -""" -2nd order stiffly accurate Rosenbrock-Wanner W-method with 3 internal stages with B_PR consistent of order 2 with (Rinf=0). -""", -"ROS2S", -references = """ -- Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 -""") -ROS2S - - -""" - ROS3Tableau() -E. Hairer, G. Wanner, Solving ordinary differential equations II, -stiff and differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) -With coefficients from https://doi.org/10.1016/S1352-2310(97)83212-8 - -""" -function ROS3Tableau() # 3rd order - gamma=0.435866521508459 - Alpha=[0 0 0; - 0.435866521508459 0 0; - 0.435866521508459 0 0] - Gamma=[gamma 0 0; - -0.19294655696029095 gamma 0; - 0 1.7492714812579468 gamma] - B=[-0.7545741238540432,1.9410040706196443, -0.18642994676560104] - Bhat=[-1.5335874578414959, 2.817451311486258, -0.28386385364476185] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_docstring( -""" -3rd order L-stable Rosenbrock method with 3 internal stages with an embedded strongly -A-stable 2nd order method. -""", -"ROS3", -references = """ -- E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and - differential-algebraic problems. Computational mathematics (2nd revised ed.), Springer (1996) -""") ROS3 - - -""" - ROS3PRTableau() - -3nd order stiffly accurate Rosenbrock-Wanner method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73. - -Rang, Joachim (2014): The Prothero and Robinson example: -Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 -""" -function ROS3PRTableau() # 3rd order - gamma=7.88675134594813e-01 - Alpha=[0 0 0; - 2.36602540378444e+00 0 0; - 0.00000000000000e+00 1.0000000000000e+00 0] - Gamma=[gamma 0 0; - -2.36602540378444e+00 gamma 0; - -2.84686425165674e-01 -1.08133897861876e+00 gamma] - B=[2.92663844023951e-01,-8.13389786187641e-02, 7.88675134594813e-01] - Bhat=[1.11324865405187e-01, 1.00000000000000e-01, 7.88675134594813e-01] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_docstring( -""" -3nd order stiffly accurate Rosenbrock method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73. -""", -"ROS3PR", -references = """ -- Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 -""") ROS3PR - - - -""" - Scholz4_7Tableau() - -3nd order stiffly accurate Rosenbrock method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73 -Convergence with order 4 for the stiff case, but has a poor accuracy. - -Rang, Joachim (2014): The Prothero and Robinson example: -Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 -""" -function Scholz4_7Tableau() # 3rd order - gamma=7.88675134594813e-01 - Alpha=[0 0 0; - 2.36602540378444e+00 0 0; - 2.50000000000000e-01 1.0000000000000e+00 0] - Gamma=[gamma 0 0; - -2.36602540378444e+00 gamma 0; - -6.13414364537605e-01 -1.10383267558217e+00 gamma] - B=[4.95076910424059e-01,-1.12898126628685e-01, 6.17821216204626e-01] - Bhat=[3.33333333333333e-01, 3.33333333333333e-01, 3.33333333333333e-01] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_docstring( -""" -3nd order stiffly accurate Rosenbrock method with 3 internal stages with B_PR consistent of order 3, which is strongly A-stable with Rinf~=-0.73. -Convergence with order 4 for the stiff case, but has a poor accuracy. -""", -"Scholz4_7", -references = """ -- Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 -""") Scholz4_7 - - -""" - @ROS23(part) - -Generate code for the 3 step ROS methods: ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7 -`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. -`@ROS23(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. -`@ROS23(:cache)` should be placed in `caches/rosenbrock_caches.jl`. -`@ROS23(:init)` and `@ROS23(:performstep)` should be placed in -`perform_step/rosenbrock_perform_step.jl`. -""" -macro ROS23(part) - tabmask=Ros23dummyTableau() - cachename=:ROS23Cache - constcachename=:ROS23ConstantCache - ROS2PRtabname=:ROS2PRTableau - ROS2Stabname=:ROS2STableau - ROS3tabname=:ROS3Tableau - ROS3PRtabname=:ROS3PRTableau - Scholz4_7tabname=:Scholz4_7Tableau - n_normalstep=length(tabmask.b)-1 - if part.value==:tableau - tabstructexpr=gen_tableau_struct(tabmask,:Ros23Tableau) - tabexprs=Array{Expr,1}([tabstructexpr]) - push!(tabexprs,gen_tableau(ROS2PRTableau(),tabstructexpr,ROS2PRtabname)) - push!(tabexprs,gen_tableau(ROS2STableau(),tabstructexpr,ROS2Stabname)) - push!(tabexprs,gen_tableau(ROS3Tableau(),tabstructexpr,ROS3tabname)) - push!(tabexprs,gen_tableau(ROS3PRTableau(),tabstructexpr,ROS3PRtabname)) - push!(tabexprs,gen_tableau(Scholz4_7Tableau(),tabstructexpr,Scholz4_7tabname)) - return esc(quote $(tabexprs...) end) - elseif part.value==:cache - constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) - cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS2PR,ROS2PRtabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS2S,ROS2Stabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3,ROS3tabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3PR,ROS3PRtabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:Scholz4_7,Scholz4_7tabname)) - return esc(quote $(cacheexprs...) end) - elseif part.value==:init - return esc(gen_initialize(cachename,constcachename)) - elseif part.value==:performstep - performstepexprs=Array{Expr,1}() - push!(performstepexprs,gen_constant_perform_step(tabmask,constcachename,n_normalstep)) - push!(performstepexprs,gen_perform_step(tabmask,cachename,n_normalstep)) - return esc(quote $(performstepexprs...) end) - else - throw(ArgumentError("Unknown parameter!")) - nothing - end -end - - - - -# 4 step ROS Methods -""" - ROS34PW1aTableau() - -L-Stable, Rosenbrock-W method with order 3 and 4 inner steps - -Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial -differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. -""" -function ROS34PW1aTableau() - gamma=4.358665215084590e-1 - Alpha=[0 0 0 0; - 2.218787467653286 0 0 0; - 0 0 0 0; # can reduce one function call with specialized perform_step - 1.208587690772214 7.511610241919324e-2 0.5 0] - Gamma=[ gamma 0 0 0; - -2.218787467653286 gamma 0 0; - -9.461966143940745e-2 -7.913526735718213e-3 gamma 0; - -1.870323744195384 -9.624340112825115e-2 2.726301276675511e-1 gamma] - B=[3.285609536316354e-1,-5.785609536316354e-1,0.25,1] - Bhat=[-0.25,0,0.25,1]#B-Bhat[3:4]==[0,0] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - ROS34PW1bTableau() - -L-Stable, Rosenbrock-W method with order 3 and 4 inner steps - -Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial -differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. -""" -function ROS34PW1bTableau() - gamma=4.358665215084590e-1 - Alpha=[0 0 0 0; - 2.218787467653286 0 0 0; - 2.218787467653286 0 0 0; # can reduce one function call with specialized perform_step - 1.453923375357884 0 0.1 0] - Gamma=[ gamma 0 0 0; - -2.218787467653286 gamma 0 0; - -2.848610224639349 -5.267530183845237e-2 gamma 0; - -1.128167857898393 -1.677546870499461e-1 5.452602553351021e-2 gamma] - B=[5.495647928937977e-1,-5.507258170857301e-1,0.25,7.511610241919324e-1] - Bhat=[-1.161024191932427e-3,0,0.25,7.511610241919324e-1]#B-Bhat[3:4]==[0,0] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - ROS34PW2Tableau() - -A stiffy accurate Rosenbrock-W method with order 3 and 4 inner steps whose -embedded method is strongly A-stable with Rinf~=0.48 - -Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial -differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. -""" -function ROS34PW2Tableau() - gamma=4.3586652150845900e-1 - Alpha=[0 0 0 0; - 8.7173304301691801e-1 0 0 0; - 8.4457060015369423e-1 -1.1299064236484185e-1 0 0; - 0 0 1 0] - Gamma=[ gamma 0 0 0; - -8.7173304301691801e-1 gamma 0 0; - -9.0338057013044082e-1 5.4180672388095326e-2 gamma 0; - 2.4212380706095346e-1 -1.2232505839045147 5.4526025533510214e-1 gamma] - B=[2.4212380706095346e-1,-1.2232505839045147,1.5452602553351020,4.3586652150845900e-1] - Bhat=[3.7810903145819369e-1,-9.6042292212423178e-2,0.5,2.1793326075422950e-1] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - ROS34PW3Tableau() - -an A-stable (Rinf~=0.63), Rosenbrock-W method with order 4 and 4 inner steps. - -Rang, J., & Angermann, L. (2005). New Rosenbrock W-methods of order 3 for partial -differential algebraic equations of index 1. BIT Numerical Mathematics, 45(4), 761-787. -""" -function ROS34PW3Tableau()#4th order - gamma=1.0685790213016289 - Alpha=[0 0 0 0; - 2.5155456020628817 0 0 0; - 5.0777280103144085e-1 0.75 0 0; - 1.3959081404277204e-1 -3.3111001065419338e-1 8.2040559712714178e-1 0] - Gamma=[ gamma 0 0 0; - -2.5155456020628817 gamma 0 0; - -8.7991339217106512e-1 -9.6014187766190695e-1 gamma 0; - -4.1731389379448741e-1 4.1091047035857703e-1 -1.3558873204765276 gamma] - B=[2.2047681286931747e-1,2.7828278331185935e-3,7.1844787635140066e-3,7.6955588053404989e-1] - Bhat=[3.1300297285209688e-1,-2.8946895245112692e-1,9.7646597959903003e-1,0] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -""" - ROS34PRwTableau() - -3rd order stiffly accurate Rosenbrock-Wanner W-method with 4 internal stages, -B_PR consistent of order 2. -The order of convergence decreases if medium stiff problems are considered. - -Joachim Rang, Improved traditional Rosenbrock-Wanner methods for stiff ODEs and DAEs, -Journal of Computational and Applied Mathematics: https://doi.org/10.1016/j.cam.2015.03.010 -""" -function ROS34PRwTableau() # 3rd order - gamma=4.3586652150845900e-01 - Alpha=[0 0 0 0; - 8.7173304301691801e-01 0 0 0; - 1.4722022879435914e+00 -3.1840250568090289e-01 0 0; - 8.1505192016694938e-01 0.5 -3.1505192016694938e-01 0] - Gamma=[ gamma 0 0 0; - -8.7173304301691801e-01 gamma 0 0; - -1.2855347382089872e+00 5.0507005541550687e-01 gamma 0; - -4.8201449182864348e-01 2.1793326075422950e-01 -1.7178529043404503e-01 gamma] - B=[3.3303742833830591e-01, 7.1793326075422947e-01, -4.8683721060099439e-01, 4.3586652150845900e-01] - Bhat=[0.25, 7.4276119608319180e-01, -3.1472922970066219e-01, 3.2196803361747034e-01] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_wanner_docstring( -""" -3rd order stiffly accurate Rosenbrock-Wanner W-method with 4 internal stages, -B_PR consistent of order 2. -The order of convergence decreases if medium stiff problems are considered. -""", -"ROS34PRw", -references = """ -- Joachim Rang, Improved traditional Rosenbrock–Wanner methods for stiff ODEs and DAEs, - Journal of Computational and Applied Mathematics, - https://doi.org/10.1016/j.cam.2015.03.010 -""") ROS34PRw - -""" - ROS3PRLTableau() - -3rd order stiffly accurate Rosenbrock-Wanner method with 4 internal stages, -B_PR consistent of order 2 with Rinf=0. -The order of convergence decreases if medium stiff problems are considered, but it has good results for very stiff cases. - -Rang, Joachim (2014): The Prothero and Robinson example: -Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 -""" -function ROS3PRLTableau() # 3rd order - gamma=4.3586652150845900e-01 - Alpha=[0 0 0 0; - 5.00000000000000e-01 0 0 0; - 5.00000000000000e-01 5.00000000000000e-01 0 0; - 5.00000000000000e-01 5.00000000000000e-01 0 0] - Gamma=[ gamma 0 0 0; - -5.00000000000000e-01 gamma 0 0; - -7.91564804204642e-01 3.52442167927514e-01 gamma 0; - -4.97889699145187e-01 3.86075154415805e-01 -3.24051976779077e-01 gamma] - B=[2.11030085481324e-03, 8.86075154415805e-01, -3.24051976779077e-01, 4.35866521508459e-01] - Bhat=[0.5, 3.87524229532982e-01, -2.09492263150452e-01, 3.21968033617470e-01] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_docstring( -""" -3rd order stiffly accurate Rosenbrock method with 4 internal stages, -B_PR consistent of order 2 with Rinf=0. -The order of convergence decreases if medium stiff problems are considered, but it has good results for very stiff cases. -""", -"ROS3PRL", -references = """ -- Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 -""") ROS3PRL - - -""" - ROS3PRL2Tableau() - -3rd order stiffly accurate Rosenbrock method with 4 internal stages, -B_PR consistent of order 3. -The order of convergence does NOT decreases if medium stiff problems are considered as it does for [`ROS3PRL`](@ref). - -Rang, Joachim (2014): The Prothero and Robinson example: -Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. https://doi.org/10.24355/dbbs.084-201408121139-0 -""" -function ROS3PRL2Tableau() # 3rd order - gamma=4.35866521508459e-01 - Alpha=[0 0 0 0; - 1.30759956452538e+00 0 0 0; - 5.00000000000000e-01 5.00000000000000e-01 0 0; - 5.00000000000000e-01 5.00000000000000e-01 0 0] - Gamma=[gamma 0 0 0; - -1.30759956452538e+00 gamma 0 0; - -7.09885758609722e-01 -5.59967359602778e-01 gamma 0; - -1.55508568075521e-01 -9.53885165751122e-01 6.73527212318184e-01 gamma] - B=[3.44491431924479e-01,-4.53885165751122e-01, 6.73527212318184e-01, 4.35866521508459e-01] - Bhat=[5.00000000000000e-01, -2.57388120865221e-01, 4.35420087247750e-01, 3.21968033617470e-01] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_docstring( -""" -3rd order stiffly accurate Rosenbrock method with 4 internal stages, -B_PR consistent of order 3. -The order of convergence does NOT decreases if medium stiff problems are considered as it does for [`ROS3PRL`](@ref). -""", -"ROS3PRL2", -references = """ -- Rang, Joachim (2014): The Prothero and Robinson example: - Convergence studies for Runge-Kutta and Rosenbrock-Wanner methods. - https://doi.org/10.24355/dbbs.084-201408121139-0 -""") ROS3PRL2 - - -""" - ROK4aTableau() - -4rd order L-stable Rosenbrock-Krylov method with 4 internal stages, -with a 3rd order embedded method which is strongly A-stable with Rinf~=0.55. (when using exact Jacobians) -Tranquilli, Paul and Sandu, Adrian (2014): Rosenbrock--Krylov Methods for Large Systems of Differential Equations -https://doi.org/10.1137/130923336 -""" -function ROK4aTableau() # 4rd order - gamma=0.572816062482135 - Alpha=[0 0 0 0; - 1 0 0 0; - 0.10845300169319391758 0.39154699830680608241 0 0; - 0.43453047756004477624 0.14484349252001492541 -0.07937397008005970166 0] - Gamma=[gamma 0 0 0; - -1.91153192976055097824 gamma 0 0; - 0.32881824061153522156 0.0 gamma 0; - 0.03303644239795811290 -0.24375152376108235312 -0.17062602991994029834 gamma] - B= [0.16666666666666666667, 0.16666666666666666667, 0.0, 0.66666666666666666667] - Bhat=[0.50269322573684235345, 0.27867551969005856226, 0.21863125457309908428, 0.0] - a,C,b,btilde,d,c=_transformtab(Alpha,Gamma,B,Bhat) - RosenbrockAdaptiveTableau(a,C,b,btilde,gamma,d,c) -end - -@doc rosenbrock_wanner_docstring( -""" -4rd order L-stable Rosenbrock-Krylov method with 4 internal stages, -with a 3rd order embedded method which is strongly A-stable with Rinf~=0.55. (when using exact Jacobians) -""", -"ROK4a", -references = """ -- Tranquilli, Paul and Sandu, Adrian (2014): - Rosenbrock--Krylov Methods for Large Systems of Differential Equations - https://doi.org/10.1137/130923336 -""") ROK4a - -""" - @ROS34PW(part) - -Generate code for the 4 steps ROS34PW methods: ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw, ROS3PRL, ROS3PRL2, ROK4a. -`part` should be one of `:tableau`, `:cache`, `:init`, `:performstep`. -`@ROS34PW(:tableau)` should be placed in `tableaus/rosenbrock_tableaus.jl`. -`@ROS34PW(:cache)` should be placed in `caches/rosenbrock_caches.jl`. -`@ROS34PW(:init)` and `@ROS34PW(:performstep)` should be placed in -`perform_step/rosenbrock_perform_step.jl`. -""" -macro ROS34PW(part) - tabmask=Ros34dummyTableau() - cachename=:ROS34PWCache - constcachename=:ROS34PWConstantCache - ROS34PW1atabname=:ROS34PW1aTableau - ROS34PW1btabname=:ROS34PW1bTableau - ROS34PW2tabname=:ROS34PW2Tableau - ROS34PW3tabname=:ROS34PW3Tableau - ROS34PRwtabname=:ROS34PRwTableau - ROS3PRLtabname=:ROS3PRLTableau - ROS3PRL2tabname=:ROS3PRL2Tableau - ROK4atabname=:ROK4aTableau - n_normalstep=length(tabmask.b)-1 - if part.value==:tableau - tabstructexpr=gen_tableau_struct(tabmask,:Ros34Tableau) - tabexprs=Array{Expr,1}([tabstructexpr]) - push!(tabexprs,gen_tableau(ROS34PW1aTableau(),tabstructexpr,ROS34PW1atabname)) - push!(tabexprs,gen_tableau(ROS34PW1bTableau(),tabstructexpr,ROS34PW1btabname)) - push!(tabexprs,gen_tableau(ROS34PW2Tableau(),tabstructexpr,ROS34PW2tabname)) - push!(tabexprs,gen_tableau(ROS34PW3Tableau(),tabstructexpr,ROS34PW3tabname)) - push!(tabexprs,gen_tableau(ROS34PRwTableau(),tabstructexpr,ROS34PRwtabname)) - push!(tabexprs,gen_tableau(ROS3PRLTableau(),tabstructexpr,ROS3PRLtabname)) - push!(tabexprs,gen_tableau(ROS3PRL2Tableau(),tabstructexpr,ROS3PRL2tabname)) - push!(tabexprs,gen_tableau(ROK4aTableau(),tabstructexpr,ROK4atabname)) - return esc(quote $(tabexprs...) end) - elseif part.value==:cache - constcacheexpr,cacheexpr=gen_cache_struct(tabmask,cachename,constcachename) - cacheexprs=Array{Expr,1}([constcacheexpr,cacheexpr]) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW1a,ROS34PW1atabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW1b,ROS34PW1btabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW2,ROS34PW2tabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PW3,ROS34PW3tabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS34PRw,ROS34PRwtabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3PRL,ROS3PRLtabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROS3PRL2,ROS3PRL2tabname)) - push!(cacheexprs,gen_algcache(cacheexpr,constcachename,:ROK4a,ROK4atabname)) - return esc(quote $(cacheexprs...) end) - elseif part.value==:init - return esc(gen_initialize(cachename,constcachename)) - elseif part.value==:performstep - performstepexprs=Array{Expr,1}() - push!(performstepexprs,gen_constant_perform_step(tabmask,constcachename,n_normalstep)) - push!(performstepexprs,gen_perform_step(tabmask,cachename,n_normalstep)) - return esc(quote $(performstepexprs...) end) - else - throw(ArgumentError("Unknown parameter!")) - nothing - end -end - -#========================================================================================= -# How to add a new method -1. `OrdinaryDiffEq.jl`: export -2. `alg_utils.jl`: alg_order(alg::)= - if the method is a W-method, add isWmethod(alg::) = true as well -3. `algorithms.jl`: add algorithm struct -4. `generic_rosenbrock.jl`: - a. write dummy tableau function (or generate from actual tableau using _masktab) for generating - table struct, cache struct and perform_step - b. write tableau function. When only `Alpha, Gamma, B, Bhat` are given, use _transformtab - c. write macro with :tableau, :cache, :init and :performstep - d. put the macros in the right places. -5. test\algconvergence\ode_rosenbrock_tests.jl: add a test for your method -# How to refactor methods into generic ones -RUN CONVERGENCE TESTS BETWEEN ANY OF THE TWO STEPS! -1. write tableau function and macro definition in this file -2. replace the tableau function (usually named with `XXXConstCache()`) using `gen_tableau()` - and the original tableau struct expression in `tableaus/rosenbrock_tableaus.jl` -3. replace the `perform_step!` methods in `perform_step/rosenbrock_perform_step.jl` using - `gen_perform_step()` and `gen_constant_perform_step()` -4. replace cache struct and `alg_cache` in `caches/rosenbrock_caches.jl` using `gen_cache_struct()` - and `gen_algcache()` -5. If the method only have 3rd-order Hermite interpolation, you can replace `initialize!()` - in `perform_step/rosenbrock_perform_step.jl` with `gen_initialize()` -DONE - -# How to debug -Use macroexpand like `macroexpand(OrdinaryDiffEq,:(@ROS34PW(:performstep)))` and check the -generated codes. - -`Revise.jl` is not compatible with macros. One may want to manually re-eval files that use -the macro like `@eval OrdinaryDiffEq include(...)` - -# If you want to refactor Rosenbrock methods ... -You need to change respective places in this file. -1. `perform_step/rosenbrock_perform_step.jl` -> `gen_perform_step()`, `gen_constant_perform_step()`, - `gen_initialize()` and special step expressions in macro definitions -2. `caches/rosenbrock_caches.jl` -> `gen_algcache()`, `gen_cache_struct()` -3. `tableaus/rosenbrock_tableaus.jl` -> `gen_tableau_struct()` and `gen_tableau()` -=========================================================================================# diff --git a/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl b/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl deleted file mode 100644 index 3f83339bd3..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/integrator_interface.jl +++ /dev/null @@ -1,34 +0,0 @@ -@inline function DiffEqBase.get_du!(out, integrator::ODEIntegrator) - integrator.cache isa FunctionMapCache || - integrator.cache isa FunctionMapConstantCache && - error("Derivatives are not defined for this stepper.") - if integrator.cache isa FunctionMapCache - out .= integrator.cache.tmp - else - return if isdefined(integrator, :fsallast) && - !(integrator.alg isa - Union{Rosenbrock23, Rosenbrock32, Rodas23W, - Rodas3P, Rodas4, Rodas4P, Rodas4P2, Rodas5, - Rodas5P, Rodas5Pe, Rodas5Pr}) - # Special stiff interpolations do not store the right value in fsallast - out .= integrator.fsallast - else - integrator(out, integrator.t, Val{1}) - end - end -end - -@inline function DiffEqBase.get_tmp_cache(integrator, - alg::OrdinaryDiffEqRosenbrockAdaptiveAlgorithm, - cache::OrdinaryDiffEqMutableCache) - (cache.tmp, cache.linsolve_tmp) -end - -function resize_non_user_cache!(integrator::ODEIntegrator, - cache::RosenbrockMutableCache, i) - cache.J = similar(cache.J, i, i) - cache.W = similar(cache.W, i, i) - resize_jac_config!(cache.jac_config, i) - resize_grad_config!(cache.grad_config, i) - nothing -end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl b/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl deleted file mode 100644 index 85b496887e..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/integrator_utils.jl +++ /dev/null @@ -1,32 +0,0 @@ -function apply_step!(integrator) - update_uprev!(integrator) - - #Update dt if adaptive or if fixed and the dt is allowed to change - if integrator.opts.adaptive || integrator.dtchangeable - integrator.dt = integrator.dtpropose - elseif integrator.dt != integrator.dtpropose && !integrator.dtchangeable - error("The current setup does not allow for changing dt.") - end - - # Update fsal if needed - if has_discontinuity(integrator) && - first_discontinuity(integrator) == integrator.tdir * integrator.t - handle_discontinuities!(integrator) - get_current_isfsal(integrator.alg, integrator.cache) && reset_fsal!(integrator) - elseif all_fsal(integrator.alg, integrator.cache) || - get_current_isfsal(integrator.alg, integrator.cache) - if integrator.reeval_fsal || integrator.u_modified || - (integrator.alg isa DP8 && !integrator.opts.calck) || - (integrator.alg isa Union{Rosenbrock23, Rosenbrock32} && - !integrator.opts.adaptive) - reset_fsal!(integrator) - else # Do not reeval_fsal, instead copyto! over - if isinplace(integrator.sol.prob) - recursivecopy!(integrator.fsalfirst, integrator.fsallast) - else - integrator.fsalfirst = integrator.fsallast - end - end - end - return nothing -end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl b/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl deleted file mode 100644 index 4273153492..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/interp_func.jl +++ /dev/null @@ -1,28 +0,0 @@ -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Rosenbrock23ConstantCache, - Rosenbrock32ConstantCache, - Rosenbrock23Cache, - Rosenbrock32Cache}} - dense ? "specialized 2nd order \"free\" stiffness-aware interpolation" : - "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Rosenbrock5ConstantCache, - Rosenbrock5Cache}} - dense ? "specialized 4rd order \"free\" stiffness-aware interpolation" : - "1st order linear" -end - -function DiffEqBase.interp_summary(::Type{cacheType}, - dense::Bool) where { - cacheType <: - Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache, - Rodas4Cache, Rodas23WCache, Rodas3PCache}} - dense ? "specialized 3rd order \"free\" stiffness-aware interpolation" : - "1st order linear" -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl deleted file mode 100644 index e2eb013809..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl +++ /dev/null @@ -1,1143 +0,0 @@ -abstract type RosenbrockMutableCache <: OrdinaryDiffEqMutableCache end -################################################################################ - -# Shampine's Low-order Rosenbrocks - -@cache mutable struct Rosenbrock23Cache{uType, rateType, uNoUnitsType, JType, WType, - TabType, TFType, UFType, F, JCType, GCType, - RTolType, A, AV, StepLimiter, StageLimiter} <: RosenbrockMutableCache - u::uType - uprev::uType - k₁::rateType - k₂::rateType - k₃::rateType - du1::rateType - du2::rateType - f₁::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - reltol::RTolType - alg::A - algebraic_vars::AV - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -TruncatedStacktraces.@truncate_stacktrace Rosenbrock23Cache 1 - -@cache mutable struct Rosenbrock32Cache{uType, rateType, uNoUnitsType, JType, WType, - TabType, TFType, UFType, F, JCType, GCType, - RTolType, A, AV, StepLimiter, StageLimiter} <: RosenbrockMutableCache - u::uType - uprev::uType - k₁::rateType - k₂::rateType - k₃::rateType - du1::rateType - du2::rateType - f₁::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - reltol::RTolType - alg::A - algebraic_vars::AV - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -function alg_cache(alg::Rosenbrock23, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k₁ = zero(rate_prototype) - k₂ = zero(rate_prototype) - k₃ = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - # f₀ = zero(u) fsalfirst - f₁ = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rosenbrock23Tableau(constvalue(uBottomEltypeNoUnits)) - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2, Val(false)) - algebraic_vars = f.mass_matrix === I ? nothing : - [all(iszero, x) for x in eachcol(f.mass_matrix)] - - Rosenbrock23Cache(u, uprev, k₁, k₂, k₃, du1, du2, f₁, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, - linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, algebraic_vars, alg.step_limiter!, - alg.stage_limiter!) -end - -function alg_cache(alg::Rosenbrock32, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - k₁ = zero(rate_prototype) - k₂ = zero(rate_prototype) - k₃ = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - # f₀ = zero(u) fsalfirst - f₁ = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rosenbrock32Tableau(constvalue(uBottomEltypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2, Val(false)) - algebraic_vars = f.mass_matrix === I ? nothing : - [all(iszero, x) for x in eachcol(f.mass_matrix)] - - Rosenbrock32Cache(u, uprev, k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, - tmp, atmp, weight, tab, tf, uf, linsolve_tmp, linsolve, jac_config, - grad_config, reltol, alg, algebraic_vars, alg.step_limiter!, alg.stage_limiter!) -end - -struct Rosenbrock23ConstantCache{T, TF, UF, JType, WType, F, AD} <: - OrdinaryDiffEqConstantCache - c₃₂::T - d::T - tf::TF - uf::UF - J::JType - W::WType - linsolve::F - autodiff::AD -end - -function Rosenbrock23ConstantCache(::Type{T}, tf, uf, J, W, linsolve, autodiff) where {T} - tab = Rosenbrock23Tableau(T) - Rosenbrock23ConstantCache(tab.c₃₂, tab.d, tf, uf, J, W, linsolve, autodiff) -end - -function alg_cache(alg::Rosenbrock23, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rosenbrock23ConstantCache(constvalue(uBottomEltypeNoUnits), tf, uf, J, W, linsolve, - alg_autodiff(alg)) -end - -struct Rosenbrock32ConstantCache{T, TF, UF, JType, WType, F, AD} <: - OrdinaryDiffEqConstantCache - c₃₂::T - d::T - tf::TF - uf::UF - J::JType - W::WType - linsolve::F - autodiff::AD -end - -function Rosenbrock32ConstantCache(::Type{T}, tf, uf, J, W, linsolve, autodiff) where {T} - tab = Rosenbrock32Tableau(T) - Rosenbrock32ConstantCache(tab.c₃₂, tab.d, tf, uf, J, W, linsolve, autodiff) -end - -function alg_cache(alg::Rosenbrock32, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rosenbrock32ConstantCache(constvalue(uBottomEltypeNoUnits), tf, uf, J, W, linsolve, - alg_autodiff(alg)) -end - -################################################################################ - -### 3rd order specialized Rosenbrocks - -struct Rosenbrock33ConstantCache{TF, UF, Tab, JType, WType, F} <: - OrdinaryDiffEqConstantCache - tf::TF - uf::UF - tab::Tab - J::JType - W::WType - linsolve::F -end - -@cache mutable struct Rosenbrock33Cache{uType, rateType, uNoUnitsType, JType, WType, - TabType, TFType, UFType, F, JCType, GCType, - RTolType, A, StepLimiter, StageLimiter} <: RosenbrockMutableCache - u::uType - uprev::uType - du::rateType - du1::rateType - du2::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - reltol::RTolType - alg::A - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -function alg_cache(alg::ROS3P, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = ROS3PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rosenbrock33Cache(u, uprev, du, du1, du2, k1, k2, k3, k4, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, - linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -function alg_cache(alg::ROS3P, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rosenbrock33ConstantCache(tf, uf, - ROS3PTableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve) -end - -@cache mutable struct Rosenbrock34Cache{uType, rateType, uNoUnitsType, JType, WType, - TabType, TFType, UFType, F, JCType, GCType, StepLimiter, StageLimiter} <: - RosenbrockMutableCache - u::uType - uprev::uType - du::rateType - du1::rateType - du2::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -function alg_cache(alg::Rodas3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rosenbrock34Cache(u, uprev, du, du1, du2, k1, k2, k3, k4, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, - linsolve_tmp, - linsolve, jac_config, grad_config, alg.step_limiter!, - alg.stage_limiter!) -end - -struct Rosenbrock34ConstantCache{TF, UF, Tab, JType, WType, F} <: - OrdinaryDiffEqConstantCache - tf::TF - uf::UF - tab::Tab - J::JType - W::WType - linsolve::F -end - -function alg_cache(alg::Rodas3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rosenbrock34ConstantCache(tf, uf, - Rodas3Tableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve) -end - -################################################################################ - -### ROS2 methods - -@ROS2(:cache) - -################################################################################ - -### ROS23 methods - -@ROS23(:cache) - -################################################################################ - -### ROS34PW methods - -@ROS34PW(:cache) - -################################################################################ - -### ROS4 methods - -@Rosenbrock4(:cache) -jac_cache(c::Rosenbrock4Cache) = (c.J, c.W) - -############################################################################### - -### Rodas methods - -struct Rodas23WConstantCache{TF, UF, Tab, JType, WType, F, AD} <: - OrdinaryDiffEqConstantCache - tf::TF - uf::UF - tab::Tab - J::JType - W::WType - linsolve::F - autodiff::AD -end - -struct Rodas3PConstantCache{TF, UF, Tab, JType, WType, F, AD} <: OrdinaryDiffEqConstantCache - tf::TF - uf::UF - tab::Tab - J::JType - W::WType - linsolve::F - autodiff::AD -end - -@cache mutable struct Rodas23WCache{uType, rateType, uNoUnitsType, JType, WType, TabType, - TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: - RosenbrockMutableCache - u::uType - uprev::uType - dense1::rateType - dense2::rateType - dense3::rateType - du::rateType - du1::rateType - du2::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - reltol::RTolType - alg::A - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -@cache mutable struct Rodas3PCache{uType, rateType, uNoUnitsType, JType, WType, TabType, - TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: - RosenbrockMutableCache - u::uType - uprev::uType - dense1::rateType - dense2::rateType - dense3::rateType - du::rateType - du1::rateType - du2::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - reltol::RTolType - alg::A - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -function alg_cache(alg::Rodas23W, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - dense3 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas3PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rodas23WCache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, k5, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace Rodas23WCache 1 -function alg_cache(alg::Rodas3P, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - dense3 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas3PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rodas3PCache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, k5, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace Rodas3PCache 1 - -function alg_cache(alg::Rodas23W, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rodas23WConstantCache(tf, uf, - Rodas3PTableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve, - alg_autodiff(alg)) -end - -function alg_cache(alg::Rodas3P, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rodas3PConstantCache(tf, uf, - Rodas3PTableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve, - alg_autodiff(alg)) -end - -### Rodas4 methods - -struct Rodas4ConstantCache{TF, UF, Tab, JType, WType, F, AD} <: OrdinaryDiffEqConstantCache - tf::TF - uf::UF - tab::Tab - J::JType - W::WType - linsolve::F - autodiff::AD -end - -@cache mutable struct Rodas4Cache{uType, rateType, uNoUnitsType, JType, WType, TabType, - TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: - RosenbrockMutableCache - u::uType - uprev::uType - dense1::rateType - dense2::rateType - du::rateType - du1::rateType - du2::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - reltol::RTolType - alg::A - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -function alg_cache(alg::Rodas4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, - k5, k6, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace Rodas4Cache 1 - -function alg_cache(alg::Rodas4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rodas4ConstantCache(tf, uf, - Rodas4Tableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve, - alg_autodiff(alg)) -end - -function alg_cache(alg::Rodas42, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas42Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, - k5, k6, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -function alg_cache(alg::Rodas42, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rodas4ConstantCache(tf, uf, - Rodas42Tableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve, - alg_autodiff(alg)) -end - -function alg_cache(alg::Rodas4P, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas4PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, - k5, k6, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -function alg_cache(alg::Rodas4P, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rodas4ConstantCache(tf, uf, - Rodas4PTableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve, - alg_autodiff(alg)) -end - -function alg_cache(alg::Rodas4P2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas4P2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rodas4Cache(u, uprev, dense1, dense2, du, du1, du2, k1, k2, k3, k4, - k5, k6, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -function alg_cache(alg::Rodas4P2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rodas4ConstantCache(tf, uf, - Rodas4P2Tableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve, - alg_autodiff(alg)) -end - -################################################################################ - -### Rosenbrock5 - -struct Rosenbrock5ConstantCache{TF, UF, Tab, JType, WType, F} <: OrdinaryDiffEqConstantCache - tf::TF - uf::UF - tab::Tab - J::JType - W::WType - linsolve::F -end - -@cache mutable struct Rosenbrock5Cache{ - uType, rateType, uNoUnitsType, JType, WType, TabType, - TFType, UFType, F, JCType, GCType, RTolType, A, StepLimiter, StageLimiter} <: - RosenbrockMutableCache - u::uType - uprev::uType - dense1::rateType - dense2::rateType - dense3::rateType - du::rateType - du1::rateType - du2::rateType - k1::rateType - k2::rateType - k3::rateType - k4::rateType - k5::rateType - k6::rateType - k7::rateType - k8::rateType - fsalfirst::rateType - fsallast::rateType - dT::rateType - J::JType - W::WType - tmp::rateType - atmp::uNoUnitsType - weight::uNoUnitsType - tab::TabType - tf::TFType - uf::UFType - linsolve_tmp::rateType - linsolve::F - jac_config::JCType - grad_config::GCType - reltol::RTolType - alg::A - step_limiter!::StepLimiter - stage_limiter!::StageLimiter -end - -TruncatedStacktraces.@truncate_stacktrace Rosenbrock5Cache 1 - -function alg_cache(alg::Rodas5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - dense3 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rosenbrock5Cache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, - k5, k6, k7, k8, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, - linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -function alg_cache(alg::Rodas5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rosenbrock5ConstantCache(tf, uf, - Rodas5Tableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve) -end - -function alg_cache( - alg::Union{Rodas5P, Rodas5Pe, Rodas5Pr}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - dense1 = zero(rate_prototype) - dense2 = zero(rate_prototype) - dense3 = zero(rate_prototype) - du = zero(rate_prototype) - du1 = zero(rate_prototype) - du2 = zero(rate_prototype) - k1 = zero(rate_prototype) - k2 = zero(rate_prototype) - k3 = zero(rate_prototype) - k4 = zero(rate_prototype) - k5 = zero(rate_prototype) - k6 = zero(rate_prototype) - k7 = zero(rate_prototype) - k8 = zero(rate_prototype) - fsalfirst = zero(rate_prototype) - fsallast = zero(rate_prototype) - dT = zero(rate_prototype) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(true)) - tmp = zero(rate_prototype) - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - weight = similar(u, uEltypeNoUnits) - recursivefill!(weight, false) - tab = Rodas5PTableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - - tf = TimeGradientWrapper(f, uprev, p) - uf = UJacobianWrapper(f, t, p) - linsolve_tmp = zero(rate_prototype) - linprob = LinearProblem(W, _vec(linsolve_tmp); u0 = _vec(tmp)) - Pl, Pr = wrapprecs( - alg.precs(W, nothing, u, p, t, nothing, nothing, nothing, - nothing)..., weight, tmp) - linsolve = init(linprob, alg.linsolve, alias_A = true, alias_b = true, - Pl = Pl, Pr = Pr, - assumptions = LinearSolve.OperatorAssumptions(true)) - grad_config = build_grad_config(alg, f, tf, du1, t) - jac_config = build_jac_config(alg, f, uf, du1, uprev, u, tmp, du2) - Rosenbrock5Cache(u, uprev, dense1, dense2, dense3, du, du1, du2, k1, k2, k3, k4, - k5, k6, k7, k8, - fsalfirst, fsallast, dT, J, W, tmp, atmp, weight, tab, tf, uf, - linsolve_tmp, - linsolve, jac_config, grad_config, reltol, alg, alg.step_limiter!, - alg.stage_limiter!) -end - -function alg_cache( - alg::Union{Rodas5P, Rodas5Pe, Rodas5Pr}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tf = TimeDerivativeWrapper(f, u, p) - uf = UDerivativeWrapper(f, t, p) - J, W = build_J_W(alg, u, uprev, p, t, dt, f, uEltypeNoUnits, Val(false)) - linprob = nothing #LinearProblem(W,copy(u); u0=copy(u)) - linsolve = nothing #init(linprob,alg.linsolve,alias_A=true,alias_b=true) - Rosenbrock5ConstantCache(tf, uf, - Rodas5PTableau(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)), J, W, linsolve) -end - -################################################################################ - -### RosenbrockW6S4O - -@RosenbrockW6S4OS(:cache) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl deleted file mode 100644 index 6f50205cf1..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl +++ /dev/null @@ -1,367 +0,0 @@ -### Fallbacks to capture - -ROSENBROCKS_WITH_INTERPOLATIONS = Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache, - Rodas23WConstantCache, Rodas3PConstantCache, - Rodas23WCache, Rodas3PCache, - Rodas4ConstantCache, Rosenbrock5ConstantCache, - Rodas4Cache, Rosenbrock5Cache} - -function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::ROSENBROCKS_WITH_INTERPOLATIONS, - idxs, T::Type{Val{D}}, differential_vars) where {D} - throw(DerivativeOrderNotPossibleError()) -end - -function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::ROSENBROCKS_WITH_INTERPOLATIONS, - idxs, T::Type{Val{D}}, differential_vars) where {D} - throw(DerivativeOrderNotPossibleError()) -end - -#### - -""" -From MATLAB ODE Suite by Shampine -""" -@def rosenbrock2332unpack begin - if cache isa OrdinaryDiffEqMutableCache - d = cache.tab.d - else - d = cache.d - end -end - -@def rosenbrock2332pre0 begin - @rosenbrock2332unpack - c1 = Θ * (1 - Θ) / (1 - 2d) - c2 = Θ * (Θ - 2d) / (1 - 2d) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, - Rosenbrock32ConstantCache}, idxs::Nothing, - T::Type{Val{0}}, differential_vars) - @rosenbrock2332pre0 - @inbounds y₀ + dt * (c1 * k[1] + c2 * k[2]) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23Cache, Rosenbrock32Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars) - @rosenbrock2332pre0 - @inbounds @.. broadcast=false y₀+dt * (c1 * k[1] + c2 * k[2]) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache - }, idxs, T::Type{Val{0}}, differential_vars) - @rosenbrock2332pre0 - @.. broadcast=false y₀[idxs]+dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, - Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache - }, idxs::Nothing, T::Type{Val{0}}, differential_vars) - @rosenbrock2332pre0 - @inbounds @.. broadcast=false out=y₀ + dt * (c1 * k[1] + c2 * k[2]) - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, - Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache - }, idxs, T::Type{Val{0}}, differential_vars) - @rosenbrock2332pre0 - @views @.. broadcast=false out=y₀[idxs] + dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) - out -end - -# First Derivative of the dense output -@def rosenbrock2332pre1 begin - @rosenbrock2332unpack - c1diff = (1 - 2 * Θ) / (1 - 2 * d) - c2diff = (2 * Θ - 2 * d) / (1 - 2 * d) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache - }, idxs::Nothing, T::Type{Val{1}}, differential_vars) - @rosenbrock2332pre1 - @.. broadcast=false c1diff * k[1]+c2diff * k[2] -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache - }, idxs, T::Type{Val{1}}, differential_vars) - @rosenbrock2332pre1 - @.. broadcast=false c1diff * k[1][idxs]+c2diff * k[2][idxs] -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, - Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache - }, idxs::Nothing, T::Type{Val{1}}, differential_vars) - @rosenbrock2332pre1 - @.. broadcast=false out=c1diff * k[1] + c2diff * k[2] - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock23ConstantCache, - Rosenbrock23Cache, - Rosenbrock32ConstantCache, Rosenbrock32Cache - }, idxs, T::Type{Val{1}}, differential_vars) - @rosenbrock2332pre1 - @views @.. broadcast=false out=c1diff * k[1][idxs] + c2diff * k[2][idxs] - out -end - -""" -From MATLAB ODE Suite by Shampine -""" -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @inbounds Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) -end - -@muladd function _ode_interpolant( - Θ, dt, y₀, y₁, k, cache::Union{Rodas4Cache, Rodas23WCache, Rodas3PCache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @inbounds @.. broadcast=false Θ1 * y₀+Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, - Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, - idxs, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @.. broadcast=false Θ1 * y₀[idxs]+Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, - Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @.. broadcast=false out=Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, - Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, - idxs, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @views @.. broadcast=false out=Θ1 * y₀[idxs] + - Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) - out -end - -# First Derivative -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas23WConstantCache, Rodas3PConstantCache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars) - @inbounds (k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁) / dt -end - -@muladd function _ode_interpolant( - Θ, dt, y₀, y₁, k, cache::Union{Rodas4Cache, Rodas23WCache, Rodas3PCache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars) - @inbounds @.. broadcast=false (k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + - y₁)/dt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, - Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, - idxs, T::Type{Val{1}}, differential_vars) - @.. broadcast=false (k[1][idxs] + - Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] - 3 * k[2][idxs] * Θ) - - y₀[idxs] + y₁[idxs])/dt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, - Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars) - @.. broadcast=false out=(k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁) / - dt - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rodas4ConstantCache, Rodas4Cache, Rodas23WConstantCache, - Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, - idxs, T::Type{Val{1}}, differential_vars) - @views @.. broadcast=false out=(k[1][idxs] + - Θ * - (-2 * k[1][idxs] + 2 * k[2][idxs] - - 3 * k[2][idxs] * Θ) - - y₀[idxs] + y₁[idxs]) / dt - out -end - -#- - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, - idxs::Nothing, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @inbounds Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, - T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @inbounds @.. broadcast=false Θ1 * y₀+Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @.. broadcast=false Θ1 * - y₀[idxs]+Θ * (y₁[idxs] + - Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs::Nothing, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @.. broadcast=false out=Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{0}}, differential_vars) - Θ1 = 1 - Θ - @views @.. broadcast=false out=Θ1 * y₀[idxs] + - Θ * (y₁[idxs] + - Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) - out -end - -# First Derivative -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, - idxs::Nothing, T::Type{Val{1}}, differential_vars) - @inbounds (k[1] + - Θ * (-2 * k[1] + 2 * k[2] + Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + - y₁) / dt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, - T::Type{Val{1}}, differential_vars) - @inbounds @.. broadcast=false (k[1] + - Θ * (-2 * k[1] + 2 * k[2] + - Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + y₁)/dt -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{1}}, differential_vars) - @.. broadcast=false (k[1][idxs] + - Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] + - Θ * (-3 * k[2][idxs] + 3 * k[3][idxs] - 4 * Θ * k[3][idxs])) - - y₀[idxs] + y₁[idxs])/dt -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs::Nothing, T::Type{Val{1}}, differential_vars) - @.. broadcast=false out=(k[1] + - Θ * (-2 * k[1] + 2 * k[2] + - Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + y₁) / dt - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{1}}, differential_vars) - @views @.. broadcast=false out=(k[1][idxs] + - Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] + - Θ * - (-3 * k[2][idxs] + 3 * k[3][idxs] - 4 * Θ * k[3][idxs])) - - y₀[idxs] + y₁[idxs]) / dt - out -end - -# Second Derivative -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, - idxs::Nothing, T::Type{Val{2}}, differential_vars) - @inbounds (-2 * k[1] + 2 * k[2] + Θ * (-6 * k[2] + 6 * k[3] - 12 * Θ * k[3])) / dt^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, - T::Type{Val{2}}, differential_vars) - @inbounds @.. broadcast=false (-2 * k[1] + 2 * k[2] + - Θ * (-6 * k[2] + 6 * k[3] - 12 * Θ * k[3]))/dt^2 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{2}}, differential_vars) - @.. broadcast=false (-2 * k[1][idxs] + 2 * k[2][idxs] + - Θ * (-6 * k[2][idxs] + 6 * k[3][idxs] - 12 * Θ * k[3][idxs]))/dt^2 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs::Nothing, T::Type{Val{2}}, differential_vars) - @.. broadcast=false out=(-2 * k[1] + 2 * k[2] + - Θ * (-6 * k[2] + 6 * k[3] - 12 * Θ * k[3])) / dt^2 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{2}}, differential_vars) - @views @.. broadcast=false out=(-2 * k[1][idxs] + 2 * k[2][idxs] + - Θ * - (-6 * k[2][idxs] + 6 * k[3][idxs] - 12 * Θ * k[3][idxs])) / - dt^2 - out -end - -# Third Derivative -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5ConstantCache, - idxs::Nothing, T::Type{Val{3}}, differential_vars) - @inbounds (-6 * k[2] + 6 * k[3] - 24 * Θ * k[3]) / dt^3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, cache::Rosenbrock5Cache, idxs::Nothing, - T::Type{Val{3}}, differential_vars) - @inbounds @.. broadcast=false (-6 * k[2] + 6 * k[3] - 24 * Θ * k[3])/dt^3 -end - -@muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{3}}, differential_vars) - @.. broadcast=false (-6 * k[2][idxs] + 6 * k[3][idxs] - 24 * Θ * k[3][idxs])/dt^3 -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs::Nothing, T::Type{Val{3}}, differential_vars) - @.. broadcast=false out=(-6 * k[2] + 6 * k[3] - 24 * Θ * k[3]) / dt^3 - out -end - -@muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{Rosenbrock5ConstantCache, Rosenbrock5Cache}, - idxs, T::Type{Val{3}}, differential_vars) - @views @.. broadcast=false out=(-6 * k[2][idxs] + 6 * k[3][idxs] - - 24 * Θ * k[3][idxs]) / dt^3 - out -end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl deleted file mode 100644 index 8cd2ffd1f3..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl +++ /dev/null @@ -1,1989 +0,0 @@ -function initialize!(integrator, cache::Union{Rosenbrock23Cache, - Rosenbrock32Cache}) - integrator.kshortsize = 2 - @unpack k₁, k₂, fsalfirst, fsallast = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = fsallast - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = k₁ - integrator.k[2] = k₂ - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 -end - -function initialize!(integrator, - cache::Union{Rosenbrock23ConstantCache, - Rosenbrock32ConstantCache}) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = zero(integrator.fsalfirst) - integrator.k[2] = zero(integrator.fsalfirst) -end - -@muladd function perform_step!(integrator, cache::Rosenbrock23Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p, opts = integrator - @unpack k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, tmp, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache - @unpack c₃₂, d = cache.tab - - # Assignments - sizeu = size(u) - mass_matrix = integrator.f.mass_matrix - - # Precalculations - γ = dt * d - dto2 = dt / 2 - dto6 = dt / 6 - - if repeat_step - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 - end - - calc_rosenbrock_differentiation!(integrator, cache, γ, γ, repeat_step, false) - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - - if repeat_step - linres = dolinsolve( - integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = γ)) - else - linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = γ)) - end - - vecu = _vec(linres.u) - veck₁ = _vec(k₁) - - @.. broadcast=false veck₁=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + dto2 * k₁ - stage_limiter!(u, integrator, p, t + dto2) - f(f₁, u, p, t + dto2) - integrator.stats.nf += 1 - - if mass_matrix === I - copyto!(tmp, k₁) - else - mul!(_vec(tmp), mass_matrix, _vec(k₁)) - end - - @.. broadcast=false linsolve_tmp=f₁ - tmp - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - vecu = _vec(linres.u) - veck2 = _vec(k₂) - - @.. broadcast=false veck2=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false k₂+=k₁ - @.. broadcast=false u=uprev + dt * k₂ - stage_limiter!(u, integrator, p, t + dt) - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - f(fsallast, u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=fsallast - c₃₂ * (k₂ - f₁) - - 2(k₁ - fsalfirst) + dt * dT - else - @.. broadcast=false du2=c₃₂ * k₂ + 2k₁ - mul!(_vec(du1), mass_matrix, _vec(du2)) - @.. broadcast=false linsolve_tmp=fsallast - du1 + c₃₂ * f₁ + 2fsalfirst + - dt * dT - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - vecu = _vec(linres.u) - veck3 = _vec(k₃) - @.. broadcast=false veck3=-vecu - - integrator.stats.nsolve += 1 - - if mass_matrix === I - @.. broadcast=false tmp=dto6 * (k₁ - 2 * k₂ + k₃) - else - veck₁ = _vec(k₁) - veck₂ = _vec(k₂) - veck₃ = _vec(k₃) - vectmp = _vec(tmp) - @.. broadcast=false vectmp=ifelse(cache.algebraic_vars, - false, dto6 * (veck₁ - 2 * veck₂ + veck₃)) - end - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - - if mass_matrix !== I - algvar = reshape(cache.algebraic_vars, size(u)) - @.. broadcast=false atmp=ifelse(algvar, fsallast, false) / - integrator.opts.abstol - integrator.EEst += integrator.opts.internalnorm(atmp, t) - end - end - cache.linsolve = linres.cache -end - -@muladd function perform_step!(integrator, cache::Rosenbrock32Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p, opts = integrator - @unpack k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, tmp, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache - @unpack c₃₂, d = cache.tab - - # Assignments - sizeu = size(u) - mass_matrix = integrator.f.mass_matrix - - # Precalculations - γ = dt * d - dto2 = dt / 2 - dto6 = dt / 6 - - if repeat_step - f(integrator.fsalfirst, uprev, p, t) - integrator.stats.nf += 1 - end - - calc_rosenbrock_differentiation!(integrator, cache, γ, γ, repeat_step, false) - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - - if repeat_step - linres = dolinsolve( - integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = γ)) - else - linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = γ)) - end - - vecu = _vec(linres.u) - veck₁ = _vec(k₁) - - @.. broadcast=false veck₁=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + dto2 * k₁ - stage_limiter!(u, integrator, p, t + dto2) - f(f₁, u, p, t + dto2) - integrator.stats.nf += 1 - - if mass_matrix === I - tmp .= k₁ - else - mul!(_vec(tmp), mass_matrix, _vec(k₁)) - end - - @.. broadcast=false linsolve_tmp=f₁ - tmp - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - vecu = _vec(linres.u) - veck2 = _vec(k₂) - - @.. broadcast=false veck2=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false k₂+=k₁ - @.. broadcast=false tmp=uprev + dt * k₂ - stage_limiter!(u, integrator, p, t + dt) - f(fsallast, tmp, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=fsallast - c₃₂ * (k₂ - f₁) - 2(k₁ - fsalfirst) + - dt * dT - else - @.. broadcast=false du2=c₃₂ * k₂ + 2k₁ - mul!(_vec(du1), mass_matrix, _vec(du2)) - @.. broadcast=false linsolve_tmp=fsallast - du1 + c₃₂ * f₁ + 2fsalfirst + dt * dT - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - vecu = _vec(linres.u) - veck3 = _vec(k₃) - - @.. broadcast=false veck3=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + dto6 * (k₁ + 4k₂ + k₃) - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - @.. broadcast=false tmp=dto6 * (k₁ - 2 * k₂ + k₃) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - - if mass_matrix !== I - @.. broadcast=false atmp=ifelse(cache.algebraic_vars, fsallast, false) / - integrator.opts.abstol - integrator.EEst += integrator.opts.internalnorm(atmp, t) - end - end - cache.linsolve = linres.cache -end - -@muladd function perform_step!(integrator, cache::Rosenbrock23ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack c₃₂, d, tf, uf = cache - - # Precalculations - γ = dt * d - dto2 = dt / 2 - dto6 = dt / 6 - - if repeat_step - integrator.fsalfirst = f(uprev, p, t) - integrator.stats.nf += 1 - end - - mass_matrix = integrator.f.mass_matrix - - # Time derivative - dT = calc_tderivative(integrator, cache) - - W = calc_W(integrator, cache, γ, repeat_step) - if !issuccess_W(W) - integrator.EEst = 2 - return nothing - end - - k₁ = _reshape(W \ -_vec((integrator.fsalfirst + γ * dT)), axes(uprev)) - integrator.stats.nsolve += 1 - f₁ = f(uprev + dto2 * k₁, p, t + dto2) - integrator.stats.nf += 1 - - if mass_matrix === I - k₂ = _reshape(W \ -_vec(f₁ - k₁), axes(uprev)) + k₁ - else - k₂ = _reshape(W \ -_vec(f₁ - mass_matrix * k₁), axes(uprev)) + k₁ - end - integrator.stats.nsolve += 1 - u = uprev + dt * k₂ - - if integrator.opts.adaptive - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - k₃ = _reshape( - W \ - -_vec((integrator.fsallast - c₃₂ * (k₂ - f₁) - - 2 * (k₁ - integrator.fsalfirst) + dt * dT)), - axes(uprev)) - else - linsolve_tmp = integrator.fsallast - mass_matrix * (c₃₂ * k₂ + 2 * k₁) + - c₃₂ * f₁ + 2 * integrator.fsalfirst + dt * dT - k₃ = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - end - integrator.stats.nsolve += 1 - - if u isa Number - utilde = dto6 * f.mass_matrix[1, 1] * (k₁ - 2 * k₂ + k₃) - else - utilde = dto6 * f.mass_matrix * (k₁ - 2 * k₂ + k₃) - end - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - - if mass_matrix !== I - atmp = @. ifelse(!integrator.differential_vars, integrator.fsallast, false) ./ - integrator.opts.abstol - integrator.EEst += integrator.opts.internalnorm(atmp, t) - end - end - integrator.k[1] = k₁ - integrator.k[2] = k₂ - integrator.u = u - return nothing -end - -@muladd function perform_step!(integrator, cache::Rosenbrock32ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack c₃₂, d, tf, uf = cache - - # Precalculations - γ = dt * d - dto2 = dt / 2 - dto6 = dt / 6 - - mass_matrix = integrator.f.mass_matrix - - if repeat_step - integrator.fsalfirst = f(uprev, p, t) - integrator.stats.nf += 1 - end - - # Time derivative - dT = calc_tderivative(integrator, cache) - - W = calc_W(integrator, cache, γ, repeat_step) - if !issuccess_W(W) - integrator.EEst = 2 - return nothing - end - - k₁ = _reshape(W \ -_vec((integrator.fsalfirst + γ * dT)), axes(uprev)) - integrator.stats.nsolve += 1 - f₁ = f(uprev + dto2 * k₁, p, t + dto2) - integrator.stats.nf += 1 - - if mass_matrix === I - k₂ = _reshape(W \ -_vec(f₁ - k₁), axes(uprev)) + k₁ - else - linsolve_tmp = f₁ - mass_matrix * k₁ - k₂ = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) + k₁ - end - - integrator.stats.nsolve += 1 - tmp = uprev + dt * k₂ - integrator.fsallast = f(tmp, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - k₃ = _reshape( - W \ - -_vec((integrator.fsallast - c₃₂ * (k₂ - f₁) - - 2(k₁ - integrator.fsalfirst) + dt * dT)), - axes(uprev)) - else - linsolve_tmp = integrator.fsallast - mass_matrix * (c₃₂ * k₂ + 2k₁) + c₃₂ * f₁ + - 2 * integrator.fsalfirst + dt * dT - k₃ = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - end - integrator.stats.nsolve += 1 - u = uprev + dto6 * (k₁ + 4k₂ + k₃) - - if integrator.opts.adaptive - utilde = dto6 * (k₁ - 2k₂ + k₃) - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - - if mass_matrix !== I - atmp = @. ifelse(!integrator.differential_vars, integrator.fsallast, false) ./ - integrator.opts.abstol - integrator.EEst += integrator.opts.internalnorm(atmp, t) - end - end - - integrator.k[1] = k₁ - integrator.k[2] = k₂ - integrator.u = u - return nothing -end - -function initialize!(integrator, - cache::Union{Rosenbrock33ConstantCache, - Rosenbrock34ConstantCache, - Rosenbrock4ConstantCache}) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function initialize!(integrator, - cache::Union{Rosenbrock33Cache, - Rosenbrock34Cache, - Rosenbrock4Cache}) - integrator.kshortsize = 2 - @unpack fsalfirst, fsallast = cache - integrator.fsalfirst = fsalfirst - integrator.fsallast = fsallast - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = fsalfirst - integrator.k[2] = fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::Rosenbrock33ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tf, uf = cache - @unpack a21, a31, a32, C21, C31, C32, b1, b2, b3, btilde1, btilde2, btilde3, gamma, c2, c3, d1, d2, d3 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtgamma = dt * gamma - - mass_matrix = integrator.f.mass_matrix - - # Time derivative - dT = calc_tderivative(integrator, cache) - - W = calc_W(integrator, cache, dtgamma, repeat_step, true) - if !issuccess_W(W) - integrator.EEst = 2 - return nothing - end - - linsolve_tmp = integrator.fsalfirst + dtd1 * dT - - k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a21 * k1 - du = f(u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd2 * dT + dtC21 * k1 - else - linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) - end - - k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a31 * k1 + a32 * k2 - du = f(u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 - else - linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) - end - - k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + b1 * k1 + b2 * k2 + b3 * k3 - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - - if integrator.opts.adaptive - utilde = btilde1 * k1 + btilde2 * k2 + btilde3 * k3 - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return nothing -end - -@muladd function perform_step!(integrator, cache::Rosenbrock33Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack du, du1, du2, fsalfirst, fsallast, k1, k2, k3, dT, J, W, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache - @unpack a21, a31, a32, C21, C31, C32, b1, b2, b3, btilde1, btilde2, btilde3, gamma, c2, c3, d1, d2, d3 = cache.tab - - # Assignments - mass_matrix = integrator.f.mass_matrix - sizeu = size(u) - utilde = du - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtgamma = dt * gamma - - calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - - if repeat_step - linres = dolinsolve( - integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - else - linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - end - - vecu = _vec(linres.u) - veck1 = _vec(k1) - - @.. broadcast=false veck1=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a21 * k1 - stage_limiter!(u, integrator, p, t + c2 * dt) - f(du, u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - vecu = _vec(linres.u) - veck2 = _vec(k2) - - @.. broadcast=false veck2=-vecu - - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 - stage_limiter!(u, integrator, p, t + c3 * dt) - f(du, u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - vecu = _vec(linres.u) - veck3 = _vec(k3) - - @.. broadcast=false veck3=-vecu - - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + b1 * k1 + b2 * k2 + b3 * k3 - - step_limiter!(u, integrator, p, t + dt) - - f(fsallast, u, p, t + dt) - integrator.stats.nf += 1 - - if integrator.opts.adaptive - @.. broadcast=false utilde=btilde1 * k1 + btilde2 * k2 + btilde3 * k3 - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - cache.linsolve = linres.cache -end - -################################################################################ - -@muladd function perform_step!(integrator, cache::Rosenbrock34ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tf, uf = cache - @unpack a21, a31, a32, a41, a42, a43, C21, C31, C32, C41, C42, C43, b1, b2, b3, b4, btilde1, btilde2, btilde3, btilde4, gamma, c2, c3, d1, d2, d3, d4 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtgamma = dt * gamma - - mass_matrix = integrator.f.mass_matrix - # Time derivative - tf.u = uprev - dT = calc_tderivative(integrator, cache) - - W = calc_W(integrator, cache, dtgamma, repeat_step, true) - if !issuccess_W(W) - integrator.EEst = 2 - return nothing - end - - linsolve_tmp = integrator.fsalfirst + dtd1 * dT - - k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev # +a21*k1 a21 == 0 - # du = f(u, p, t+c2*dt) c2 == 0 and a21 == 0 => du = f(uprev, p, t) == fsalfirst - - if mass_matrix === I - linsolve_tmp = integrator.fsalfirst + dtd2 * dT + dtC21 * k1 - else - linsolve_tmp = integrator.fsalfirst + dtd2 * dT + mass_matrix * (dtC21 * k1) - end - - k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a31 * k1 + a32 * k2 - du = f(u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 - else - linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) - end - - k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a41 * k1 + a42 * k2 + a43 * k3 - du = f(u, p, t + dt) #-- c4 = 1 - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd4 * dT + dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - else - linsolve_tmp = du + dtd4 * dT + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - end - - k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - - if integrator.opts.adaptive - utilde = btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 - atmp = calculate_residuals(utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return nothing -end - -@muladd function perform_step!(integrator, cache::Rosenbrock34Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack du, du1, du2, fsalfirst, fsallast, k1, k2, k3, k4, dT, J, W, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache - @unpack a21, a31, a32, a41, a42, a43, C21, C31, C32, C41, C42, C43, b1, b2, b3, b4, btilde1, btilde2, btilde3, btilde4, gamma, c2, c3, d1, d2, d3, d4 = cache.tab - - # Assignments - uidx = eachindex(integrator.uprev) - sizeu = size(u) - mass_matrix = integrator.f.mass_matrix - utilde = du - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtgamma = dt * gamma - - calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - - if repeat_step - linres = dolinsolve( - integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - else - linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), - du = integrator.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - end - - vecu = _vec(linres.u) - veck1 = _vec(k1) - - @.. broadcast=false veck1=-vecu - integrator.stats.nsolve += 1 - - #= - a21 == 0 and c2 == 0 - so du = integrator.fsalfirst! - @.. broadcast=false u = uprev + a21*k1 - - f(du, u, p, t+c2*dt) - =# - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=fsalfirst + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=fsalfirst + dtd2 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck2 = _vec(k2) - @.. broadcast=false veck2=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 - stage_limiter!(u, integrator, p, t + c3 * dt) - f(du, u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + dtC31 * k1 + dtC32 * k2 - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck3 = _vec(k3) - @.. broadcast=false veck3=-vecu - integrator.stats.nsolve += 1 - @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 - stage_limiter!(u, integrator, p, t + dt) - f(du, u, p, t + dt) #-- c4 = 1 - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + dtC41 * k1 + dtC42 * k2 + - dtC43 * k3 - else - @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck4 = _vec(k4) - @.. broadcast=false veck4=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + b1 * k1 + b2 * k2 + b3 * k3 + b4 * k4 - - step_limiter!(u, integrator, p, t + dt) - - f(fsallast, u, p, t + dt) - integrator.stats.nf += 1 - - if integrator.opts.adaptive - @.. broadcast=false utilde=btilde1 * k1 + btilde2 * k2 + btilde3 * k3 + btilde4 * k4 - calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - cache.linsolve = linres.cache -end - -################################################################################ - -#### ROS2 type method - -@ROS2(:init) -@ROS2(:performstep) - -################################################################################ - -#### ROS23 type method - -@ROS23(:init) -@ROS23(:performstep) - -################################################################################ - -#### ROS34PW type method - -@ROS34PW(:init) -@ROS34PW(:performstep) - -################################################################################ - -#### ROS4 type method - -@Rosenbrock4(:performstep) - -################################################################################ - -#### Rodas3P type method - -function initialize!(integrator, cache::Union{Rodas23WConstantCache, Rodas3PConstantCache}) - integrator.kshortsize = 3 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - # Avoid undefined entries if k is an array of arrays - integrator.k[1] = zero(integrator.u) - integrator.k[2] = zero(integrator.u) - integrator.k[3] = zero(integrator.u) -end - -@muladd function perform_step!( - integrator, cache::Union{Rodas23WConstantCache, Rodas3PConstantCache}, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tf, uf = cache - @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtgamma = dt * gamma - - mass_matrix = integrator.f.mass_matrix - - # Time derivative - tf.u = uprev - dT = calc_tderivative(integrator, cache) - - W = calc_W(integrator, cache, dtgamma, repeat_step, true) - if !issuccess_W(W) - integrator.EEst = 2 - return nothing - end - - du = f(uprev, p, t) - integrator.stats.nf += 1 - k3 = copy(du) #-- save for stage 3 - - linsolve_tmp = du + dtd1 * dT - - k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a21 * k1 - du = f(u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd2 * dT + dtC21 * k1 - else - linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) - end - - k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - - if mass_matrix === I - linsolve_tmp = k3 + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - else - linsolve_tmp = k3 + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) - end - - k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a41 * k1 + a42 * k2 + a43 * k3 - du = f(u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - linsolve_tmp = du + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - end - - k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - - if mass_matrix === I - linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - else - linsolve_tmp = du + - mass_matrix * (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - end - - k5 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - du = u + k4 #-- solution p=2 - u = u + k5 #-- solution p=3 - - EEst = 0.0 - if integrator.opts.calck - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab - integrator.k[1] = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 - integrator.k[2] = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 - integrator.k[3] = h2_21 * k1 + h2_22 * k2 + h2_23 * k3 + h2_24 * k4 + h2_25 * k5 - if integrator.opts.adaptive - if isa(linsolve_tmp, AbstractFloat) - u_int, u_diff = calculate_interpoldiff( - uprev, du, u, integrator.k[1], integrator.k[2], integrator.k[3]) - else - u_int = linsolve_tmp - u_diff = linsolve_tmp .+ 0 - calculate_interpoldiff!(u_int, u_diff, uprev, du, u, integrator.k[1], - integrator.k[2], integrator.k[3]) - end - atmp = calculate_residuals(u_diff, uprev, u_int, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) #-- role of t unclear - end - end - - if (integrator.alg isa Rodas23W) - k1 = u .+ 0 - u = du .+ 0 - du = k1 .+ 0 - if integrator.opts.calck - integrator.k[1] = integrator.k[3] .+ 0 - integrator.k[2] = 0 * integrator.k[2] - end - end - - if integrator.opts.adaptive - atmp = calculate_residuals(u - du, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) - end - - integrator.u = u - return nothing -end - -function initialize!(integrator, cache::Union{Rodas23WCache, Rodas3PCache}) - integrator.kshortsize = 3 - @unpack dense1, dense2, dense3 = cache - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = dense1 - integrator.k[2] = dense2 - integrator.k[3] = dense3 -end - -@muladd function perform_step!( - integrator, cache::Union{Rodas23WCache, Rodas3PCache}, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack du, du1, du2, dT, J, W, uf, tf, k1, k2, k3, k4, k5, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache - @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab - - # Assignments - sizeu = size(u) - uidx = eachindex(integrator.uprev) - mass_matrix = integrator.f.mass_matrix - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtgamma = dt * gamma - - f(cache.fsalfirst, uprev, p, t) # used in calc_rosenbrock_differentiation! - integrator.stats.nf += 1 - - calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - - if repeat_step - linres = dolinsolve( - integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), - du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - else - linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), - du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - end - - @.. broadcast=false $(_vec(k1))=-linres.u - - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a21 * k1 - stage_limiter!(u, integrator, p, t + c2 * dt) - f(du, u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k2))=-linres.u - integrator.stats.nsolve += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=cache.fsalfirst + dtd3 * dT + - (dtC31 * k1 + dtC32 * k2) - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=cache.fsalfirst + dtd3 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k3))=-linres.u - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 - stage_limiter!(u, integrator, p, t + c2 * dt) - f(du, u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + - (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k4))=-linres.u - integrator.stats.nsolve += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + - (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - else - @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k5))=-linres.u - integrator.stats.nsolve += 1 - - du = u + k4 #-- p=2 solution - u .+= k5 - - step_limiter!(u, integrator, p, t + dt) - - EEst = 0.0 - if integrator.opts.calck - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab - @.. broadcast=false integrator.k[1]=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + - h25 * k5 - @.. broadcast=false integrator.k[2]=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + - h35 * k5 - @.. broadcast=false integrator.k[3]=h2_21 * k1 + h2_22 * k2 + h2_23 * k3 + - h2_24 * k4 + h2_25 * k5 - if integrator.opts.adaptive - calculate_interpoldiff!( - du1, du2, uprev, du, u, integrator.k[1], integrator.k[2], integrator.k[3]) - calculate_residuals!(atmp, du2, uprev, du1, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) #-- role of t unclear - end - end - - if (integrator.alg isa Rodas23W) - du1[:] = u[:] - u[:] = du[:] - du[:] = du1[:] - if integrator.opts.calck - integrator.k[1][:] = integrator.k[3][:] - integrator.k[2][:] .= 0.0 - end - end - - if integrator.opts.adaptive - calculate_residuals!(atmp, u - du, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = max(EEst, integrator.opts.internalnorm(atmp, t)) - end - cache.linsolve = linres.cache -end - -function calculate_interpoldiff(uprev, up2, up3, c_koeff, d_koeff, c2_koeff) - u_int = 0.0 - u_diff = 0.0 - a1 = up3 + c_koeff - up2 - c2_koeff - a2 = d_koeff - c_koeff + c2_koeff - a3 = -d_koeff - dis = a2^2 - 3 * a1 * a3 - u_int = up3 - u_diff = 0.0 - if dis > 0.0 #-- Min/Max occurs - tau1 = (-a2 - sqrt(dis)) / (3 * a3) - tau2 = (-a2 + sqrt(dis)) / (3 * a3) - if tau1 > tau2 - tau1, tau2 = tau2, tau1 - end - for tau in (tau1, tau2) - if (tau > 0.0) && (tau < 1.0) - y_tau = (1 - tau) * uprev + - tau * (up3 + (1 - tau) * (c_koeff + tau * d_koeff)) - dy_tau = ((a3 * tau + a2) * tau + a1) * tau - if abs(dy_tau) > abs(u_diff) - u_diff = dy_tau - u_int = y_tau - end - end - end - end - return u_int, u_diff -end - -function calculate_interpoldiff!(u_int, u_diff, uprev, up2, up3, c_koeff, d_koeff, c2_koeff) - for i in eachindex(up2) - a1 = up3[i] + c_koeff[i] - up2[i] - c2_koeff[i] - a2 = d_koeff[i] - c_koeff[i] + c2_koeff[i] - a3 = -d_koeff[i] - dis = a2^2 - 3 * a1 * a3 - u_int[i] = up3[i] - u_diff[i] = 0.0 - if dis > 0.0 #-- Min/Max occurs - tau1 = (-a2 - sqrt(dis)) / (3 * a3) - tau2 = (-a2 + sqrt(dis)) / (3 * a3) - if tau1 > tau2 - tau1, tau2 = tau2, tau1 - end - for tau in (tau1, tau2) - if (tau > 0.0) && (tau < 1.0) - y_tau = (1 - tau) * uprev[i] + - tau * (up3[i] + (1 - tau) * (c_koeff[i] + tau * d_koeff[i])) - dy_tau = ((a3 * tau + a2) * tau + a1) * tau - if abs(dy_tau) > abs(u_diff[i]) - u_diff[i] = dy_tau - u_int[i] = y_tau - end - end - end - end - end -end - -#### Rodas4 type method - -function initialize!(integrator, cache::Rodas4ConstantCache) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - # Avoid undefined entries if k is an array of arrays - integrator.k[1] = zero(integrator.u) - integrator.k[2] = zero(integrator.u) -end - -@muladd function perform_step!(integrator, cache::Rodas4ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tf, uf = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtgamma = dt * gamma - - mass_matrix = integrator.f.mass_matrix - - # Time derivative - tf.u = uprev - dT = calc_tderivative(integrator, cache) - - W = calc_W(integrator, cache, dtgamma, repeat_step, true) - if !issuccess_W(W) - integrator.EEst = 2 - return nothing - end - - du = f(uprev, p, t) - integrator.stats.nf += 1 - - linsolve_tmp = du + dtd1 * dT - - k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a21 * k1 - du = f(u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd2 * dT + dtC21 * k1 - else - linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) - end - - k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a31 * k1 + a32 * k2 - du = f(u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - else - linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) - end - - k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a41 * k1 + a42 * k2 + a43 * k3 - du = f(u, p, t + c4 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - linsolve_tmp = du + dtd4 * dT + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - end - - k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - du = f(u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - else - linsolve_tmp = du + - mass_matrix * (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - end - - k5 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = u + k5 - du = f(u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + (dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + dtC64 * k4 + dtC63 * k3) - else - linsolve_tmp = du + - mass_matrix * - (dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + dtC64 * k4 + dtC63 * k3) - end - - k6 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = u + k6 - - if integrator.opts.adaptive - atmp = calculate_residuals(k6, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.opts.calck - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab - integrator.k[1] = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 - integrator.k[2] = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 - end - integrator.u = u - return nothing -end - -function initialize!(integrator, cache::Rodas4Cache) - integrator.kshortsize = 2 - @unpack dense1, dense2 = cache - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = dense1 - integrator.k[2] = dense2 -end - -@muladd function perform_step!(integrator, cache::Rodas4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack du, du1, du2, dT, J, W, uf, tf, k1, k2, k3, k4, k5, k6, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab - - # Assignments - sizeu = size(u) - uidx = eachindex(integrator.uprev) - mass_matrix = integrator.f.mass_matrix - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtgamma = dt * gamma - - f(cache.fsalfirst, uprev, p, t) # used in calc_rosenbrock_differentiation! - integrator.stats.nf += 1 - - calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - - if repeat_step - linres = dolinsolve( - integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), - du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - else - linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), - du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - end - - @.. broadcast=false $(_vec(k1))=-linres.u - - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a21 * k1 - stage_limiter!(u, integrator, p, t + c2 * dt) - f(du, u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k2))=-linres.u - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 - stage_limiter!(u, integrator, p, t + c3 * dt) - f(du, u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k3))=-linres.u - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 - stage_limiter!(u, integrator, p, t + c4 * dt) - f(du, u, p, t + c4 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + - (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k4))=-linres.u - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - stage_limiter!(u, integrator, p, t + dt) - f(du, u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + - (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - else - @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k5))=-linres.u - integrator.stats.nsolve += 1 - - u .+= k5 - f(du, u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + - dtC64 * k4 + dtC63 * k3) - else - @.. broadcast=false du1=dtC61 * k1 + dtC62 * k2 + dtC65 * k5 + dtC64 * k4 + - dtC63 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - @.. broadcast=false $(_vec(k6))=-linres.u - integrator.stats.nsolve += 1 - - u .+= k6 - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - calculate_residuals!(atmp, k6, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.opts.calck - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab - @.. broadcast=false integrator.k[1]=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + - h25 * k5 - @.. broadcast=false integrator.k[2]=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + - h35 * k5 - end - cache.linsolve = linres.cache -end - -############################################################################### - -### Rodas5 Method - -function initialize!(integrator, cache::Rosenbrock5ConstantCache) - integrator.kshortsize = 3 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - # Avoid undefined entries if k is an array of arrays - integrator.k[1] = zero(integrator.u) - integrator.k[2] = zero(integrator.u) - integrator.k[3] = zero(integrator.u) -end - -@muladd function perform_step!(integrator, cache::Rosenbrock5ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack tf, uf = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - dtC71 = C71 / dt - dtC72 = C72 / dt - dtC73 = C73 / dt - dtC74 = C74 / dt - dtC75 = C75 / dt - dtC76 = C76 / dt - dtC81 = C81 / dt - dtC82 = C82 / dt - dtC83 = C83 / dt - dtC84 = C84 / dt - dtC85 = C85 / dt - dtC86 = C86 / dt - dtC87 = C87 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtd5 = dt * d5 - dtgamma = dt * gamma - - mass_matrix = integrator.f.mass_matrix - - # Time derivative - dT = calc_tderivative(integrator, cache) - - W = calc_W(integrator, cache, dtgamma, repeat_step, true) - if !issuccess_W(W) - integrator.EEst = 2 - return nothing - end - - du1 = f(uprev, p, t) - integrator.stats.nf += 1 - - linsolve_tmp = du1 + dtd1 * dT - - k1 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a21 * k1 - du = f(u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd2 * dT + dtC21 * k1 - else - linsolve_tmp = du + dtd2 * dT + mass_matrix * (dtC21 * k1) - end - - k2 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a31 * k1 + a32 * k2 - du = f(u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - else - linsolve_tmp = du + dtd3 * dT + mass_matrix * (dtC31 * k1 + dtC32 * k2) - end - - k3 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a41 * k1 + a42 * k2 + a43 * k3 - du = f(u, p, t + c4 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - linsolve_tmp = du + dtd4 * dT + mass_matrix * (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - end - - k4 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - du = f(u, p, t + c5 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + dtd5 * dT + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - else - linsolve_tmp = du + dtd5 * dT + - mass_matrix * (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - end - - k5 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 - du = f(u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + dtC65 * k5) - else - linsolve_tmp = du + - mass_matrix * - (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + dtC65 * k5) - end - - k6 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = u + k6 - du = f(u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + - (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + dtC75 * k5 + - dtC76 * k6) - else - linsolve_tmp = du + - mass_matrix * - (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + dtC75 * k5 + - dtC76 * k6) - end - - k7 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = u + k7 - du = f(u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - linsolve_tmp = du + - (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + dtC85 * k5 + - dtC86 * k6 + dtC87 * k7) - else - linsolve_tmp = du + - mass_matrix * - (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + dtC85 * k5 + - dtC86 * k6 + dtC87 * k7) - end - - k8 = _reshape(W \ -_vec(linsolve_tmp), axes(uprev)) - integrator.stats.nsolve += 1 - u = u + k8 - linsolve_tmp = k8 - - if integrator.opts.adaptive - if (integrator.alg isa Rodas5Pe) - linsolve_tmp = 0.2606326497975715 * k1 - 0.005158627295444251 * k2 + - 1.3038988631109731 * k3 + 1.235000722062074 * k4 + - -0.7931985603795049 * k5 - 1.005448461135913 * k6 - - 0.18044626132120234 * k7 + 0.17051519239113755 * k8 - end - atmp = calculate_residuals(linsolve_tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.opts.calck - @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab - integrator.k[1] = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + h26 * k6 + - h27 * k7 + h28 * k8 - integrator.k[2] = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + h36 * k6 + - h37 * k7 + h38 * k8 - integrator.k[3] = h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + h45 * k5 + h46 * k6 + - h47 * k7 + h48 * k8 - if (integrator.alg isa Rodas5Pr) && integrator.opts.adaptive && - (integrator.EEst < 1.0) - k2 = 0.5 * (uprev + u + - 0.5 * (integrator.k[1] + 0.5 * (integrator.k[2] + 0.5 * integrator.k[3]))) - du1 = (0.25 * (integrator.k[2] + integrator.k[3]) - uprev + u) / dt - du = f(k2, p, t + dt / 2) - integrator.stats.nf += 1 - if mass_matrix === I - du2 = du1 - du - else - du2 = mass_matrix * du1 - du - end - EEst = norm(du2) / (integrator.opts.abstol + integrator.opts.reltol * norm(k2)) - integrator.EEst = max(EEst, integrator.EEst) - end - end - - integrator.u = u - return nothing -end - -function initialize!(integrator, cache::Rosenbrock5Cache) - integrator.kshortsize = 3 - @unpack dense1, dense2, dense3 = cache - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = dense1 - integrator.k[2] = dense2 - integrator.k[3] = dense3 -end - -@muladd function perform_step!(integrator, cache::Rosenbrock5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack du, du1, du2, k1, k2, k3, k4, k5, k6, k7, k8, dT, J, W, uf, tf, linsolve_tmp, jac_config, atmp, weight, stage_limiter!, step_limiter! = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab - - # Assignments - sizeu = size(u) - uidx = eachindex(integrator.uprev) - mass_matrix = integrator.f.mass_matrix - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - dtC71 = C71 / dt - dtC72 = C72 / dt - dtC73 = C73 / dt - dtC74 = C74 / dt - dtC75 = C75 / dt - dtC76 = C76 / dt - dtC81 = C81 / dt - dtC82 = C82 / dt - dtC83 = C83 / dt - dtC84 = C84 / dt - dtC85 = C85 / dt - dtC86 = C86 / dt - dtC87 = C87 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtd5 = dt * d5 - dtgamma = dt * gamma - - f(cache.fsalfirst, uprev, p, t) # used in calc_rosenbrock_differentiation! - integrator.stats.nf += 1 - - calc_rosenbrock_differentiation!(integrator, cache, dtd1, dtgamma, repeat_step, true) - - calculate_residuals!(weight, fill!(weight, one(eltype(u))), uprev, uprev, - integrator.opts.abstol, integrator.opts.reltol, - integrator.opts.internalnorm, t) - - if repeat_step - linres = dolinsolve( - integrator, cache.linsolve; A = nothing, b = _vec(linsolve_tmp), - du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - else - linres = dolinsolve(integrator, cache.linsolve; A = W, b = _vec(linsolve_tmp), - du = cache.fsalfirst, u = u, p = p, t = t, weight = weight, - solverdata = (; gamma = dtgamma)) - end - - vecu = _vec(linres.u) - veck1 = _vec(k1) - - @.. broadcast=false veck1=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a21 * k1 - stage_limiter!(u, integrator, p, t + c2 * dt) - f(du, u, p, t + c2 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck2 = _vec(k2) - @.. broadcast=false veck2=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a31 * k1 + a32 * k2 - stage_limiter!(u, integrator, p, t + c3 * dt) - f(du, u, p, t + c3 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck3 = _vec(k3) - @.. broadcast=false veck3=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a41 * k1 + a42 * k2 + a43 * k3 - stage_limiter!(u, integrator, p, t + c4 * dt) - f(du, u, p, t + c4 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + - (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck4 = _vec(k4) - @.. broadcast=false veck4=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - stage_limiter!(u, integrator, p, t + c5 * dt) - f(du, u, p, t + c5 * dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd5 * dT + - (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - else - @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + dtd5 * dT + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck5 = _vec(k5) - @.. broadcast=false veck5=-vecu - integrator.stats.nsolve += 1 - - @.. broadcast=false u=uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 - stage_limiter!(u, integrator, p, t + dt) - f(du, u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + - dtC64 * k4 + dtC65 * k5) - else - @.. broadcast=false du1=dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + - dtC65 * k5 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck6 = _vec(k6) - @.. broadcast=false veck6=-vecu - integrator.stats.nsolve += 1 - - u .+= k6 - stage_limiter!(u, integrator, p, t + dt) - f(du, u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + - dtC74 * k4 + dtC75 * k5 + dtC76 * k6) - else - @.. broadcast=false du1=dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + - dtC75 * k5 + dtC76 * k6 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck7 = _vec(k7) - @.. broadcast=false veck7=-vecu - integrator.stats.nsolve += 1 - - u .+= k7 - f(du, u, p, t + dt) - integrator.stats.nf += 1 - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + - dtC84 * k4 + dtC85 * k5 + dtC86 * k6 + dtC87 * k7) - else - @.. broadcast=false du1=dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + - dtC85 * k5 + dtC86 * k6 + dtC87 * k7 - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(integrator, linres.cache; b = _vec(linsolve_tmp)) - veck8 = _vec(k8) - @.. broadcast=false veck8=-vecu - integrator.stats.nsolve += 1 - - du .= k8 - u .+= k8 - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - if (integrator.alg isa Rodas5Pe) - du = 0.2606326497975715 * k1 - 0.005158627295444251 * k2 + - 1.3038988631109731 * k3 + 1.235000722062074 * k4 + - -0.7931985603795049 * k5 - 1.005448461135913 * k6 - - 0.18044626132120234 * k7 + 0.17051519239113755 * k8 - end - calculate_residuals!(atmp, du, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.opts.calck - @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab - @.. broadcast=false integrator.k[1]=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + - h25 * k5 + h26 * k6 + h27 * k7 + h28 * k8 - @.. broadcast=false integrator.k[2]=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + - h35 * k5 + h36 * k6 + h37 * k7 + h38 * k8 - @.. broadcast=false integrator.k[3]=h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + - h45 * k5 + h46 * k6 + h47 * k7 + h48 * k8 - if (integrator.alg isa Rodas5Pr) && integrator.opts.adaptive && - (integrator.EEst < 1.0) - k2 = 0.5 * (uprev + u + - 0.5 * (integrator.k[1] + 0.5 * (integrator.k[2] + 0.5 * integrator.k[3]))) - du1 = (0.25 * (integrator.k[2] + integrator.k[3]) - uprev + u) / dt - f(du, k2, p, t + dt / 2) - integrator.stats.nf += 1 - if mass_matrix === I - du2 = du1 - du - else - mul!(_vec(du2), mass_matrix, _vec(du1)) - du2 = du2 - du - end - EEst = norm(du2) / (integrator.opts.abstol + integrator.opts.reltol * norm(k2)) - integrator.EEst = max(EEst, integrator.EEst) - end - end - cache.linsolve = linres.cache -end - -@RosenbrockW6S4OS(:init) -@RosenbrockW6S4OS(:performstep) diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl deleted file mode 100644 index 493c67111a..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl +++ /dev/null @@ -1,833 +0,0 @@ -struct Rosenbrock23Tableau{T} - c₃₂::T - d::T -end - -function Rosenbrock23Tableau(T) - c₃₂ = convert(T, 6 + sqrt(2)) - d = convert(T, 1 / (2 + sqrt(2))) - Rosenbrock23Tableau(c₃₂, d) -end - -struct Rosenbrock32Tableau{T} - c₃₂::T - d::T -end - -function Rosenbrock32Tableau(T) - c₃₂ = convert(T, 6 + sqrt(2)) - d = convert(T, 1 / (2 + sqrt(2))) - Rosenbrock32Tableau(c₃₂, d) -end - -struct ROS3PTableau{T, T2} - a21::T - a31::T - a32::T - C21::T - C31::T - C32::T - b1::T - b2::T - b3::T - btilde1::T - btilde2::T - btilde3::T - gamma::T2 - c2::T2 - c3::T2 - d1::T - d2::T - d3::T -end - -function ROS3PTableau(T, T2) - gamma = convert(T, 1 / 2 + sqrt(3) / 6) - igamma = inv(gamma) - a21 = convert(T, igamma) - a31 = convert(T, igamma) - a32 = convert(T, 0) - C21 = convert(T, -igamma^2) - tmp = -igamma * (convert(T, 2) - convert(T, 1 / 2) * igamma) - C31 = -igamma * (convert(T, 1) - tmp) - C32 = tmp - tmp = igamma * (convert(T, 2 / 3) - convert(T, 1 / 6) * igamma) - b1 = igamma * (convert(T, 1) + tmp) - b2 = tmp - b3 = convert(T, 1 / 3) * igamma - # btilde1 = convert(T,2.113248654051871) - # btilde2 = convert(T,1.000000000000000) - # btilde3 = convert(T,0.4226497308103742) - btilde1 = b1 - convert(T, 2.113248654051871) - btilde2 = b2 - convert(T, 1.000000000000000) - btilde3 = b3 - convert(T, 0.4226497308103742) - c2 = convert(T, 1) - c3 = convert(T, 1) - d1 = convert(T, 0.7886751345948129) - d2 = convert(T, -0.2113248654051871) - d3 = convert(T, -1.077350269189626) - ROS3PTableau( - a21, a31, a32, C21, C31, C32, b1, b2, b3, btilde1, btilde2, btilde3, gamma, - c2, c3, d1, d2, d3) -end - -struct Rodas3Tableau{T, T2} - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - C21::T - C31::T - C32::T - C41::T - C42::T - C43::T - b1::T - b2::T - b3::T - b4::T - btilde1::T - btilde2::T - btilde3::T - btilde4::T - gamma::T2 - c2::T2 - c3::T2 - d1::T - d2::T - d3::T - d4::T -end - -function Rodas3Tableau(T, T2) - gamma = convert(T, 1 // 2) - a21 = convert(T, 0) - a31 = convert(T, 2) - a32 = convert(T, 0) - a41 = convert(T, 2) - a42 = convert(T, 0) - a43 = convert(T, 1) - C21 = convert(T, 4) - C31 = convert(T, 1) - C32 = convert(T, -1) - C41 = convert(T, 1) - C42 = convert(T, -1) - C43 = convert(T, -8 // 3) - b1 = convert(T, 2) - b2 = convert(T, 0) - b3 = convert(T, 1) - b4 = convert(T, 1) - btilde1 = convert(T, 0.0) - btilde2 = convert(T, 0.0) - btilde3 = convert(T, 0.0) - btilde4 = convert(T, 1.0) - c2 = convert(T, 0.0) - c3 = convert(T, 1.0) - c4 = convert(T, 1.0) - d1 = convert(T, 1 // 2) - d2 = convert(T, 3 // 2) - d3 = convert(T, 0) - d4 = convert(T, 0) - Rodas3Tableau(a21, a31, a32, a41, a42, a43, C21, C31, C32, C41, C42, C43, b1, b2, b3, - b4, btilde1, btilde2, btilde3, btilde4, gamma, c2, c3, d1, d2, d3, d4) -end - -struct Rodas3PTableau{T, T2} - a21::T - a41::T - a42::T - a43::T - C21::T - C31::T - C32::T - C41::T - C42::T - C43::T - C51::T - C52::T - C53::T - C54::T - gamma::T - c2::T2 - c3::T2 - d1::T - d2::T - d3::T - h21::T - h22::T - h23::T - h24::T - h25::T - h31::T - h32::T - h33::T - h34::T - h35::T - h2_21::T - h2_22::T - h2_23::T - h2_24::T - h2_25::T -end - -function Rodas3PTableau(T, T2) - gamma = convert(T, 1 // 3) - a21 = convert(T, 4.0 / 3.0) - a41 = convert(T, 2.90625) - a42 = convert(T, 3.375) - a43 = convert(T, 0.40625) - C21 = -convert(T, 4.0) - C31 = convert(T, 8.25) - C32 = convert(T, 6.75) - C41 = convert(T, 1.21875) - C42 = -convert(T, 5.0625) - C43 = -convert(T, 1.96875) - C51 = convert(T, 4.03125) - C52 = -convert(T, 15.1875) - C53 = -convert(T, 4.03125) - C54 = convert(T, 6.0) - c2 = convert(T2, 4.0 / 9.0) - c3 = convert(T2, 0.0) - d1 = convert(T, 1.0 / 3.0) - d2 = -convert(T, 1.0 / 9.0) - d3 = convert(T, 1.0) - h21 = convert(T, 1.78125) - h22 = convert(T, 6.75) - h23 = convert(T, 0.15625) - h24 = -convert(T, 6.0) - h25 = -convert(T, 1.0) - h31 = convert(T, 4.21875) - h32 = -convert(T, 15.1875) - h33 = -convert(T, 3.09375) - h34 = convert(T, 9.0) - h35 = convert(T, 0.0) - h2_21 = convert(T, 4.21875) - h2_22 = -convert(T, 2.025) - h2_23 = -convert(T, 1.63125) - h2_24 = -convert(T, 1.7) - h2_25 = -convert(T, 0.1) - Rodas3PTableau(a21, a41, a42, a43, - C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, - gamma, c2, c3, d1, d2, d3, - h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25) -end - -@ROS2(:tableau) - -@ROS23(:tableau) - -@ROS34PW(:tableau) - -@Rosenbrock4(:tableau) - -struct RodasTableau{T, T2} - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - C21::T - C31::T - C32::T - C41::T - C42::T - C43::T - C51::T - C52::T - C53::T - C54::T - C61::T - C62::T - C63::T - C64::T - C65::T - gamma::T - c2::T2 - c3::T2 - c4::T2 - d1::T - d2::T - d3::T - d4::T - h21::T - h22::T - h23::T - h24::T - h25::T - h31::T - h32::T - h33::T - h34::T - h35::T -end - -function Rodas4Tableau(T, T2) - gamma = convert(T, 1 // 4) - #BET2P=0.0317D0 - #BET3P=0.0635D0 - #BET4P=0.3438D0 - a21 = convert(T, 1.544000000000000) - a31 = convert(T, 0.9466785280815826) - a32 = convert(T, 0.2557011698983284) - a41 = convert(T, 3.314825187068521) - a42 = convert(T, 2.896124015972201) - a43 = convert(T, 0.9986419139977817) - a51 = convert(T, 1.221224509226641) - a52 = convert(T, 6.019134481288629) - a53 = convert(T, 12.53708332932087) - a54 = -convert(T, 0.6878860361058950) - C21 = -convert(T, 5.668800000000000) - C31 = -convert(T, 2.430093356833875) - C32 = -convert(T, 0.2063599157091915) - C41 = -convert(T, 0.1073529058151375) - C42 = -convert(T, 9.594562251023355) - C43 = -convert(T, 20.47028614809616) - C51 = convert(T, 7.496443313967647) - C52 = -convert(T, 10.24680431464352) - C53 = -convert(T, 33.99990352819905) - C54 = convert(T, 11.70890893206160) - C61 = convert(T, 8.083246795921522) - C62 = -convert(T, 7.981132988064893) - C63 = -convert(T, 31.52159432874371) - C64 = convert(T, 16.31930543123136) - C65 = -convert(T, 6.058818238834054) - - c2 = convert(T2, 0.386) - c3 = convert(T2, 0.21) - c4 = convert(T2, 0.63) - - d1 = convert(T, 0.2500000000000000) - d2 = -convert(T, 0.1043000000000000) - d3 = convert(T, 0.1035000000000000) - d4 = -convert(T, 0.03620000000000023) - - h21 = convert(T, 10.12623508344586) - h22 = -convert(T, 7.487995877610167) - h23 = -convert(T, 34.80091861555747) - h24 = -convert(T, 7.992771707568823) - h25 = convert(T, 1.025137723295662) - h31 = -convert(T, 0.6762803392801253) - h32 = convert(T, 6.087714651680015) - h33 = convert(T, 16.43084320892478) - h34 = convert(T, 24.76722511418386) - h35 = -convert(T, 6.594389125716872) - - RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, - gamma, c2, c3, c4, d1, d2, d3, d4, - h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) -end - -function Rodas42Tableau(T, T2) - gamma = convert(T, 1 // 4) - #BET2P=0.0317D0 - #BET3P=0.0047369D0 - #BET4P=0.3438D0 - a21 = convert(T, 1.402888400000000) - a31 = convert(T, 0.6581212688557198) - a32 = -convert(T, 1.320936088384301) - a41 = convert(T, 7.131197445744498) - a42 = convert(T, 16.02964143958207) - a43 = -convert(T, 5.561572550509766) - a51 = convert(T, 22.73885722420363) - a52 = convert(T, 67.38147284535289) - a53 = -convert(T, 31.21877493038560) - a54 = convert(T, 0.7285641833203814) - C21 = -convert(T, 5.104353600000000) - C31 = -convert(T, 2.899967805418783) - C32 = convert(T, 4.040399359702244) - C41 = -convert(T, 32.64449927841361) - C42 = -convert(T, 99.35311008728094) - C43 = convert(T, 49.99119122405989) - C51 = -convert(T, 76.46023087151691) - C52 = -convert(T, 278.5942120829058) - C53 = convert(T, 153.9294840910643) - C54 = convert(T, 10.97101866258358) - C61 = -convert(T, 76.29701586804983) - C62 = -convert(T, 294.2795630511232) - C63 = convert(T, 162.0029695867566) - C64 = convert(T, 23.65166903095270) - C65 = -convert(T, 7.652977706771382) - c2 = convert(T2, 0.3507221) - c3 = convert(T2, 0.2557041) - c4 = convert(T2, 0.6817790) - d1 = convert(T, 0.2500000000000000) - d2 = -convert(T, 0.06902209999999998) - d3 = -convert(T, 0.0009671999999999459) - d4 = -convert(T, 0.08797900000000025) - - h21 = -convert(T, 38.71940424117216) - h22 = -convert(T, 135.8025833007622) - h23 = convert(T, 64.51068857505875) - h24 = -convert(T, 4.192663174613162) - h25 = -convert(T, 2.531932050335060) - h31 = -convert(T, 14.99268484949843) - h32 = -convert(T, 76.30242396627033) - h33 = convert(T, 58.65928432851416) - h34 = convert(T, 16.61359034616402) - h35 = -convert(T, 0.6758691794084156) - - RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, - gamma, c2, c3, c4, d1, d2, d3, d4, - h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) -end - -function Rodas4PTableau(T, T2) - gamma = convert(T, 1 // 4) - #BET2P=0.D0 - #BET3P=c3*c3*(c3/6.d0-GAMMA/2.d0)/(GAMMA*GAMMA) - #BET4P=0.3438D0 - a21 = convert(T, 3) - a31 = convert(T, 1.831036793486759) - a32 = convert(T, 0.4955183967433795) - a41 = convert(T, 2.304376582692669) - a42 = -convert(T, 0.05249275245743001) - a43 = -convert(T, 1.176798761832782) - a51 = -convert(T, 7.170454962423024) - a52 = -convert(T, 4.741636671481785) - a53 = -convert(T, 16.31002631330971) - a54 = -convert(T, 1.062004044111401) - C21 = -convert(T, 12) - C31 = -convert(T, 8.791795173947035) - C32 = -convert(T, 2.207865586973518) - C41 = convert(T, 10.81793056857153) - C42 = convert(T, 6.780270611428266) - C43 = convert(T, 19.53485944642410) - C51 = convert(T, 34.19095006749676) - C52 = convert(T, 15.49671153725963) - C53 = convert(T, 54.74760875964130) - C54 = convert(T, 14.16005392148534) - C61 = convert(T, 34.62605830930532) - C62 = convert(T, 15.30084976114473) - C63 = convert(T, 56.99955578662667) - C64 = convert(T, 18.40807009793095) - C65 = -convert(T, 5.714285714285717) - c2 = convert(T2, 3 * gamma) - c3 = convert(T2, 0.21) - c4 = convert(T2, 0.63) - d1 = convert(T, 0.2500000000000000) - d2 = convert(T, -0.5000000000000000) - d3 = convert(T, -0.0235040000000000) - d4 = convert(T, -0.0362000000000000) - - h21 = convert(T, 25.09876703708589) - h22 = convert(T, 11.62013104361867) - h23 = convert(T, 28.49148307714626) - h24 = -convert(T, 5.664021568594133) - h25 = convert(T, 0) - h31 = convert(T, 1.638054557396973) - h32 = -convert(T, 0.7373619806678748) - h33 = convert(T, 8.477918219238990) - h34 = convert(T, 15.99253148779520) - h35 = -convert(T, 1.882352941176471) - - RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, - gamma, c2, c3, c4, d1, d2, d3, d4, - h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) -end - -function Rodas4P2Tableau(T, T2) - gamma = convert(T, 1 // 4) - a21 = convert(T, 3.000000000000000) - a31 = convert(T, 0.906377755268814) - a32 = -convert(T, 0.189707390391685) - a41 = convert(T, 3.758617027739064) - a42 = convert(T, 1.161741776019525) - a43 = -convert(T, 0.849258085312803) - a51 = convert(T, 7.089566927282776) - a52 = convert(T, 4.573591406461604) - a53 = -convert(T, 8.423496976860259) - a54 = -convert(T, 0.959280113459775) - - C21 = convert(T, -12.00000000000000) - C31 = convert(T, -6.354581592719008) - C32 = convert(T, 0.338972550544623) - C41 = convert(T, -8.575016317114033) - C42 = convert(T, -7.606483992117508) - C43 = convert(T, 12.224997650124820) - C51 = convert(T, -5.888975457523102) - C52 = convert(T, -8.157396617841821) - C53 = convert(T, 24.805546872612922) - C54 = convert(T, 12.790401512796979) - C61 = convert(T, -4.408651676063871) - C62 = convert(T, -6.692003137674639) - C63 = convert(T, 24.625568527593117) - C64 = convert(T, 16.627521966636085) - C65 = convert(T, -5.714285714285718) - - c2 = convert(T2, 0.750000000000000) - c3 = convert(T2, 0.321448134013046) - c4 = convert(T2, 0.519745732277726) - d1 = convert(T, 0.250000000000000) - d2 = convert(T, -0.500000000000000) - d3 = convert(T, -0.189532918363016) - d4 = convert(T, 0.085612108792769) - - h21 = convert(T, -5.323528268423303) - h22 = convert(T, -10.042123754867493) - h23 = convert(T, 17.175254928256965) - h24 = convert(T, -5.079931171878093) - h25 = convert(T, -0.016185991706112) - h31 = convert(T, 6.984505741529879) - h32 = convert(T, 6.914061169603662) - h33 = convert(T, -0.849178943070653) - h34 = convert(T, 18.104410789349338) - h35 = convert(T, -3.516963011559032) - - RodasTableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, - gamma, c2, c3, c4, d1, d2, d3, d4, - h21, h22, h23, h24, h25, h31, h32, h33, h34, h35) -end - -struct Rodas5Tableau{T, T2} - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - C21::T - C31::T - C32::T - C41::T - C42::T - C43::T - C51::T - C52::T - C53::T - C54::T - C61::T - C62::T - C63::T - C64::T - C65::T - C71::T - C72::T - C73::T - C74::T - C75::T - C76::T - C81::T - C82::T - C83::T - C84::T - C85::T - C86::T - C87::T - gamma::T2 - d1::T - d2::T - d3::T - d4::T - d5::T - c2::T2 - c3::T2 - c4::T2 - c5::T2 - h21::T - h22::T - h23::T - h24::T - h25::T - h26::T - h27::T - h28::T - h31::T - h32::T - h33::T - h34::T - h35::T - h36::T - h37::T - h38::T - h41::T - h42::T - h43::T - h44::T - h45::T - h46::T - h47::T - h48::T -end - -function Rodas5Tableau(T, T2) - gamma = convert(T2, 0.19) - a21 = convert(T, 2.0) - a31 = convert(T, 3.040894194418781) - a32 = convert(T, 1.041747909077569) - a41 = convert(T, 2.576417536461461) - a42 = convert(T, 1.622083060776640) - a43 = convert(T, -0.9089668560264532) - a51 = convert(T, 2.760842080225597) - a52 = convert(T, 1.446624659844071) - a53 = convert(T, -0.3036980084553738) - a54 = convert(T, 0.2877498600325443) - a61 = convert(T, -14.09640773051259) - a62 = convert(T, 6.925207756232704) - a63 = convert(T, -41.47510893210728) - a64 = convert(T, 2.343771018586405) - a65 = convert(T, 24.13215229196062) - C21 = convert(T, -10.31323885133993) - C31 = convert(T, -21.04823117650003) - C32 = convert(T, -7.234992135176716) - C41 = convert(T, 32.22751541853323) - C42 = convert(T, -4.943732386540191) - C43 = convert(T, 19.44922031041879) - C51 = convert(T, -20.69865579590063) - C52 = convert(T, -8.816374604402768) - C53 = convert(T, 1.260436877740897) - C54 = convert(T, -0.7495647613787146) - C61 = convert(T, -46.22004352711257) - C62 = convert(T, -17.49534862857472) - C63 = convert(T, -289.6389582892057) - C64 = convert(T, 93.60855400400906) - C65 = convert(T, 318.3822534212147) - C71 = convert(T, 34.20013733472935) - C72 = convert(T, -14.15535402717690) - C73 = convert(T, 57.82335640988400) - C74 = convert(T, 25.83362985412365) - C75 = convert(T, 1.408950972071624) - C76 = convert(T, -6.551835421242162) - C81 = convert(T, 42.57076742291101) - C82 = convert(T, -13.80770672017997) - C83 = convert(T, 93.98938432427124) - C84 = convert(T, 18.77919633714503) - C85 = convert(T, -31.58359187223370) - C86 = convert(T, -6.685968952921985) - C87 = convert(T, -5.810979938412932) - c2 = convert(T2, 0.38) - c3 = convert(T2, 0.3878509998321533) - c4 = convert(T2, 0.4839718937873840) - c5 = convert(T2, 0.4570477008819580) - d1 = convert(T, gamma) - d2 = convert(T, -0.1823079225333714636) - d3 = convert(T, -0.319231832186874912) - d4 = convert(T, 0.3449828624725343) - d5 = convert(T, -0.377417564392089818) - - h21 = convert(T, 27.354592673333357) - h22 = convert(T, -6.925207756232857) - h23 = convert(T, 26.40037733258859) - h24 = convert(T, 0.5635230501052979) - h25 = convert(T, -4.699151156849391) - h26 = convert(T, -1.6008677469422725) - h27 = convert(T, -1.5306074446748028) - h28 = convert(T, -1.3929872940716344) - - h31 = convert(T, 44.19024239501722) - h32 = convert(T, 1.3677947663381929e-13) - h33 = convert(T, 202.93261852171622) - h34 = convert(T, -35.5669339789154) - h35 = convert(T, -181.91095152160645) - h36 = convert(T, 3.4116351403665033) - h37 = convert(T, 2.5793540257308067) - h38 = convert(T, 2.2435122582734066) - - h41 = convert(T, -44.0988150021747) - h42 = convert(T, -5.755396159656812e-13) - h43 = convert(T, -181.26175034586677) - h44 = convert(T, 56.99302194811676) - h45 = convert(T, 183.21182741427398) - h46 = convert(T, -7.480257918273637) - h47 = convert(T, -5.792426076169686) - h48 = convert(T, -5.32503859794143) - - # println("---Rodas5---") - - #= - a71 = -14.09640773051259 - a72 = 6.925207756232704 - a73 = -41.47510893210728 - a74 = 2.343771018586405 - a75 = 24.13215229196062 - a76 = convert(T,1) - a81 = -14.09640773051259 - a82 = 6.925207756232704 - a83 = -41.47510893210728 - a84 = 2.343771018586405 - a85 = 24.13215229196062 - a86 = convert(T,1) - a87 = convert(T,1) - b1 = -14.09640773051259 - b2 = 6.925207756232704 - b3 = -41.47510893210728 - b4 = 2.343771018586405 - b5 = 24.13215229196062 - b6 = convert(T,1) - b7 = convert(T,1) - b8 = convert(T,1) - =# - - Rodas5Tableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - a61, a62, a63, a64, a65, - C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, - C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, - C81, C82, C83, C84, C85, C86, C87, - gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5, - h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, - h38, h41, h42, h43, h44, h45, h46, h47, h48) -end - -function Rodas5PTableau(T, T2) - gamma = convert(T2, 0.21193756319429014) - - a21 = convert(T, 3.0) - a31 = convert(T, 2.849394379747939) - a32 = convert(T, 0.45842242204463923) - a41 = convert(T, -6.954028509809101) - a42 = convert(T, 2.489845061869568) - a43 = convert(T, -10.358996098473584) - a51 = convert(T, 2.8029986275628964) - a52 = convert(T, 0.5072464736228206) - a53 = convert(T, -0.3988312541770524) - a54 = convert(T, -0.04721187230404641) - a61 = convert(T, -7.502846399306121) - a62 = convert(T, 2.561846144803919) - a63 = convert(T, -11.627539656261098) - a64 = convert(T, -0.18268767659942256) - a65 = convert(T, 0.030198172008377946) - - C21 = convert(T, -14.155112264123755) - C31 = convert(T, -17.97296035885952) - C32 = convert(T, -2.859693295451294) - C41 = convert(T, 147.12150275711716) - C42 = convert(T, -1.41221402718213) - C43 = convert(T, 71.68940251302358) - C51 = convert(T, 165.43517024871676) - C52 = convert(T, -0.4592823456491126) - C53 = convert(T, 42.90938336958603) - C54 = convert(T, -5.961986721573306) - C61 = convert(T, 24.854864614690072) - C62 = convert(T, -3.0009227002832186) - C63 = convert(T, 47.4931110020768) - C64 = convert(T, 5.5814197821558125) - C65 = convert(T, -0.6610691825249471) - C71 = convert(T, 30.91273214028599) - C72 = convert(T, -3.1208243349937974) - C73 = convert(T, 77.79954646070892) - C74 = convert(T, 34.28646028294783) - C75 = convert(T, -19.097331116725623) - C76 = convert(T, -28.087943162872662) - C81 = convert(T, 37.80277123390563) - C82 = convert(T, -3.2571969029072276) - C83 = convert(T, 112.26918849496327) - C84 = convert(T, 66.9347231244047) - C85 = convert(T, -40.06618937091002) - C86 = convert(T, -54.66780262877968) - C87 = convert(T, -9.48861652309627) - - c2 = convert(T2, 0.6358126895828704) - c3 = convert(T2, 0.4095798393397535) - c4 = convert(T2, 0.9769306725060716) - c5 = convert(T2, 0.4288403609558664) - - d1 = convert(T, 0.21193756319429014) - d2 = convert(T, -0.42387512638858027) - d3 = convert(T, -0.3384627126235924) - d4 = convert(T, 1.8046452872882734) - d5 = convert(T, 2.325825639765069) - - h21 = convert(T, 25.948786856663858) - h22 = convert(T, -2.5579724845846235) - h23 = convert(T, 10.433815404888879) - h24 = convert(T, -2.3679251022685204) - h25 = convert(T, 0.524948541321073) - h26 = convert(T, 1.1241088310450404) - h27 = convert(T, 0.4272876194431874) - h28 = convert(T, -0.17202221070155493) - - h31 = convert(T, -9.91568850695171) - h32 = convert(T, -0.9689944594115154) - h33 = convert(T, 3.0438037242978453) - h34 = convert(T, -24.495224566215796) - h35 = convert(T, 20.176138334709044) - h36 = convert(T, 15.98066361424651) - h37 = convert(T, -6.789040303419874) - h38 = convert(T, -6.710236069923372) - - h41 = convert(T, 11.419903575922262) - h42 = convert(T, 2.8879645146136994) - h43 = convert(T, 72.92137995996029) - h44 = convert(T, 80.12511834622643) - h45 = convert(T, -52.072871366152654) - h46 = convert(T, -59.78993625266729) - h47 = convert(T, -0.15582684282751913) - h48 = convert(T, 4.883087185713722) - - Rodas5Tableau(a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - a61, a62, a63, a64, a65, - C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, - C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, - C81, C82, C83, C84, C85, C86, C87, - gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5, - h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, - h38, h41, h42, h43, h44, h45, h46, h47, h48) -end - -@RosenbrockW6S4OS(:tableau) - -#= -# alpha_ij -A = [0 0 0 0 0 0 0 0 - big"0.38" 0 0 0 0 0 0 0 - big"0.1899188971074152" big"0.1979321027247381" 0 0 0 0 0 0 - big"0.1110729281178426" big"0.5456026683145674" big"-0.1727037026450261" 0 0 0 0 0 - big"0.2329444418850307" big"0.025099380960713898" big"0.1443314046300300" big"0.054672473406183418" 0 0 0 0 - big"-0.036201017843430883" big"4.208448872731939" big"-7.549674427720996" big"-0.2076823626400282" big"4.585108935472517" 0 0 0 - big"7.585261698003052" big"-15.57426208319938" big"-8.814406895608121" big"1.534698996826085" big"16.07870828397837" big"0.19" 0 0 - big"0.4646018839086969" big"0" big"-1.720907508837576" big"0.2910480220957973" big"1.821778861539924" big"-0.046521258706842056" big"0.19" 0] -# bi -B = [big"0.464601884",0,big"-1.72090751",big"0.29104802",big"1.82177886",big"-0.02674488",big"-0.01977638",big"0.19"] - -# Beta_ij - -Beta = [big"0.19" 0 0 0 0 0 0 0 - big"0.0076920774666285364" big"0.19" 0 0 0 0 0 0 - big"-0.058129718999580252" big"-0.063251113355141360" big"0.19" 0 0 0 0 0 - big"0.7075715596134048" big"-0.5980299539145789" big"0.5294131505610923" big"0.19" 0 0 0 0 - big"-0.034975026573934865" big"-0.1928476085817357" big"0.089839586125126941" big"0.027613185520411822" big"0.19" 0 0 0 - big"7.585261698003052" big"-15.57426208319938" big"-8.814406895608121" big"1.534698996826085" big"16.07870828397837" big"0.19" 0 0 - big"0.4646018839086969" 0 big"-1.720907508837576" big"0.2910480220957973" big"1.821778861539924" big"-0.046521258706842056" big"0.19" 0 - big"0.4646018839086969" 0 big"-1.720907508837576" big"0.2910480220957973" big"1.821778861539924" big"-0.026744882930135193" big"-0.019776375776706864" big"0.19"] - -Gamma = Beta - A -a = A*Gamma -m = B'*inv(Gamma) # = b_i -C = inv(Diagonal(diag(Gamma))) - inv(Gamma) -c = sum(A,2) -D = Beta*inv(Gamma) -d = sum(Gamma,2) - -# Dense output -D_i = tanspose(D)*k_i -y1(Θ) = y₀*(1-Θ) + Θ*(y₁ + (Θ-1)*(D₂ + D₄ + (Θ + 1)*(D₃ + ΘD₄))) - -# Determining coefficients -gamma = 0.19 -c3 = 0.3878509998321533 == alpha3 -c4 = 0.4839718937873840 == alpha4 -c5 = 0.4570477008819580 == alpha5 -beta3 = 6.8619167645278386e-2 -beta4 = 0.8289547562599182 -beta5 = 7.9630136489868164e-2 -alpha64 = -0.2076823627400282 -=# diff --git a/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl b/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl deleted file mode 100644 index 6e77125e14..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl +++ /dev/null @@ -1,837 +0,0 @@ -function _ode_addsteps!(k, t, uprev, u, dt, f, p, - cache::Union{Rosenbrock23ConstantCache, - Rosenbrock32ConstantCache}, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 2 || always_calc_begin - @unpack tf, uf, d = cache - γ = dt * d - tf.u = uprev - if cache.autodiff isa AutoForwardDiff - dT = ForwardDiff.derivative(tf, t) - else - dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) - end - - mass_matrix = f.mass_matrix - if uprev isa AbstractArray - J = ForwardDiff.jacobian(uf, uprev) - W = mass_matrix - γ * J - else - J = ForwardDiff.derivative(uf, uprev) - W = 1 - γ * J - end - k₁ = W \ (f(uprev, p, t) + dt * d * dT) - f₁ = f(uprev + dt * k₁ / 2, p, t + dt / 2) - k₂ = W \ (f₁ - k₁) + k₁ - copyat_or_push!(k, 1, k₁) - copyat_or_push!(k, 2, k₂) - end - nothing -end - -function _ode_addsteps!(k, t, uprev, u, dt, f, p, - cache::Union{Rosenbrock23Cache, Rosenbrock32Cache}, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 2 || always_calc_begin - @unpack k₁, k₂, k₃, du1, du2, f₁, fsalfirst, fsallast, dT, J, W, tmp, uf, tf, linsolve_tmp, weight = cache - @unpack c₃₂, d = cache.tab - uidx = eachindex(uprev) - - # Assignments - sizeu = size(u) - mass_matrix = f.mass_matrix - γ = dt * d - dto2 = dt / 2 - dto6 = dt / 6 - - @.. broadcast=false linsolve_tmp=@muladd fsalfirst + γ * dT - - ### Jacobian does not need to be re-evaluated after an event - ### Since it's unchanged - jacobian2W!(W, mass_matrix, γ, J, false) - - linsolve = cache.linsolve - - linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), - reltol = cache.reltol) - - vecu = _vec(linres.u) - veck₁ = _vec(k₁) - - @.. broadcast=false veck₁=-vecu - - @.. broadcast=false tmp=uprev + dto2 * k₁ - f(f₁, tmp, p, t + dto2) - - if mass_matrix === I - tmp .= k₁ - else - mul!(_vec(tmp), mass_matrix, _vec(k₁)) - end - - @.. broadcast=false linsolve_tmp=f₁ - tmp - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck2 = _vec(k₂) - - @.. broadcast=false veck2=-vecu - - @.. broadcast=false k₂+=k₁ - - copyat_or_push!(k, 1, k₁) - copyat_or_push!(k, 2, k₂) - cache.linsolve = linres.cache - end - nothing -end - -function _ode_addsteps!( - k, t, uprev, u, dt, f, p, cache::Union{Rodas23WConstantCache, Rodas3PConstantCache}, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 2 || always_calc_begin - @unpack tf, uf = cache - @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtgamma = dt * gamma - mass_matrix = f.mass_matrix - - # Time derivative - tf.u = uprev - if cache.autodiff isa AutoForwardDiff - dT = ForwardDiff.derivative(tf, t) - else - dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) - end - - # Jacobian - uf.t = t - if uprev isa AbstractArray - J = ForwardDiff.jacobian(uf, uprev) - W = mass_matrix / dtgamma - J - else - J = ForwardDiff.derivative(uf, uprev) - W = 1 / dtgamma - J - end - - du = f(uprev, p, t) - k3 = copy(du) - - linsolve_tmp = du + dtd1 * dT - - k1 = W \ linsolve_tmp - u = uprev + a21 * k1 - du = f(u, p, t + c2 * dt) - - linsolve_tmp = du + dtd2 * dT + dtC21 * k1 - - k2 = W \ linsolve_tmp - - linsolve_tmp = k3 + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - - k3 = W \ linsolve_tmp - u = uprev + a41 * k1 + a42 * k2 + a43 * k3 - du = f(u, p, t + dt) - - linsolve_tmp = du + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - - k4 = W \ linsolve_tmp - - linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - - k5 = W \ linsolve_tmp - - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab - k₁ = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 - k₂ = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 - #k₃ = h2_21 * k1 + h2_22 * k2 + h2_23 * k3 + h2_24 * k4 + h2_25 * k5 - copyat_or_push!(k, 1, k₁) - copyat_or_push!(k, 2, k₂) - #copyat_or_push!(k, 3, k₃) - end - nothing -end - -function _ode_addsteps!( - k, t, uprev, u, dt, f, p, cache::Union{Rodas23WCache, Rodas3PCache}, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 2 || always_calc_begin - @unpack du, du1, du2, tmp, k1, k2, k3, k4, k5, dT, J, W, uf, tf, linsolve_tmp, jac_config, fsalfirst, weight = cache - @unpack a21, a41, a42, a43, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, gamma, c2, c3, d1, d2, d3 = cache.tab - - # Assignments - sizeu = size(u) - uidx = eachindex(uprev) - mass_matrix = f.mass_matrix - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtgamma = dt * gamma - - @.. broadcast=false linsolve_tmp=@muladd fsalfirst + dtgamma * dT - - ### Jacobian does not need to be re-evaluated after an event - ### Since it's unchanged - jacobian2W!(W, mass_matrix, dtgamma, J, true) - - linsolve = cache.linsolve - - linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck1 = _vec(k1) - - @.. broadcast=false veck1=-vecu - @.. broadcast=false tmp=uprev + a21 * k1 - f(du, tmp, p, t + c2 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck2 = _vec(k2) - @.. broadcast=false veck2=-vecu - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=fsalfirst + dtd3 * dT + - (dtC31 * k1 + dtC32 * k2) - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=fsalfirst + dtd3 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck3 = _vec(k3) - @.. broadcast=false veck3=-vecu - @.. broadcast=false tmp=uprev + a41 * k1 + a42 * k2 + a43 * k3 - f(du, tmp, p, t + dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck4 = _vec(k4) - @.. broadcast=false veck4=-vecu - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + - dtC53 * k3) - else - @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck5 = _vec(k5) - @.. broadcast=false veck5=-vecu - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35, h2_21, h2_22, h2_23, h2_24, h2_25 = cache.tab - @.. broadcast=false du=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 - copyat_or_push!(k, 1, copy(du)) - - @.. broadcast=false du=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 - copyat_or_push!(k, 2, copy(du)) - end - nothing -end - -function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rodas4ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 2 || always_calc_begin - @unpack tf, uf = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtgamma = dt * gamma - mass_matrix = f.mass_matrix - - # Time derivative - tf.u = uprev - if cache.autodiff isa AutoForwardDiff - dT = ForwardDiff.derivative(tf, t) - else - dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) - end - - # Jacobian - uf.t = t - if uprev isa AbstractArray - J = ForwardDiff.jacobian(uf, uprev) - W = mass_matrix / dtgamma - J - else - J = ForwardDiff.derivative(uf, uprev) - W = 1 / dtgamma - J - end - - du = f(uprev, p, t) - - linsolve_tmp = du + dtd1 * dT - - k1 = W \ linsolve_tmp - u = uprev + a21 * k1 - du = f(u, p, t + c2 * dt) - - linsolve_tmp = du + dtd2 * dT + dtC21 * k1 - - k2 = W \ linsolve_tmp - u = uprev + a31 * k1 + a32 * k2 - du = f(u, p, t + c3 * dt) - - linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - - k3 = W \ linsolve_tmp - u = uprev + a41 * k1 + a42 * k2 + a43 * k3 - du = f(u, p, t + c4 * dt) - - linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - - k4 = W \ linsolve_tmp - u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - du = f(u, p, t + dt) - - linsolve_tmp = du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - - k5 = W \ linsolve_tmp - - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab - k₁ = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 - k₂ = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 - copyat_or_push!(k, 1, k₁) - copyat_or_push!(k, 2, k₂) - end - nothing -end - -function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rodas4Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 2 || always_calc_begin - @unpack du, du1, du2, tmp, k1, k2, k3, k4, k5, k6, dT, J, W, uf, tf, linsolve_tmp, jac_config, fsalfirst, weight = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, gamma, c2, c3, c4, d1, d2, d3, d4 = cache.tab - - # Assignments - sizeu = size(u) - uidx = eachindex(uprev) - mass_matrix = f.mass_matrix - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtgamma = dt * gamma - - @.. broadcast=false linsolve_tmp=@muladd fsalfirst + dtgamma * dT - - ### Jacobian does not need to be re-evaluated after an event - ### Since it's unchanged - jacobian2W!(W, mass_matrix, dtgamma, J, true) - - linsolve = cache.linsolve - - linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck1 = _vec(k1) - - @.. broadcast=false veck1=-vecu - @.. broadcast=false tmp=uprev + a21 * k1 - f(du, tmp, p, t + c2 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck2 = _vec(k2) - @.. broadcast=false veck2=-vecu - @.. broadcast=false tmp=uprev + a31 * k1 + a32 * k2 - f(du, tmp, p, t + c3 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck3 = _vec(k3) - @.. broadcast=false veck3=-vecu - @.. broadcast=false tmp=uprev + a41 * k1 + a42 * k2 + a43 * k3 - f(du, tmp, p, t + c4 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + - (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck4 = _vec(k4) - @.. broadcast=false veck4=-vecu - @.. broadcast=false tmp=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - f(du, tmp, p, t + dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + - dtC53 * k3) - else - @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck5 = _vec(k5) - @.. broadcast=false veck5=-vecu - @unpack h21, h22, h23, h24, h25, h31, h32, h33, h34, h35 = cache.tab - @.. broadcast=false k6=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 - copyat_or_push!(k, 1, copy(k6)) - - @.. broadcast=false k6=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 - copyat_or_push!(k, 2, copy(k6)) - end - nothing -end - -function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rosenbrock5ConstantCache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 3 || always_calc_begin - @unpack tf, uf = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - dtC71 = C71 / dt - dtC72 = C72 / dt - dtC73 = C73 / dt - dtC74 = C74 / dt - dtC75 = C75 / dt - dtC76 = C76 / dt - dtC81 = C81 / dt - dtC82 = C82 / dt - dtC83 = C83 / dt - dtC84 = C84 / dt - dtC85 = C85 / dt - dtC86 = C86 / dt - dtC87 = C87 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtd5 = dt * d5 - dtgamma = dt * gamma - mass_matrix = f.mass_matrix - - # Time derivative - tf.u = uprev - # if cache.autodiff isa AutoForwardDiff - # dT = ForwardDiff.derivative(tf, t) - # else - dT = FiniteDiff.finite_difference_derivative(tf, t, dir = sign(dt)) - # end - - # Jacobian - uf.t = t - if uprev isa AbstractArray - J = ForwardDiff.jacobian(uf, uprev) - W = mass_matrix / dtgamma - J - else - J = ForwardDiff.derivative(uf, uprev) - W = 1 / dtgamma - J - end - - du = f(uprev, p, t) - - linsolve_tmp = du + dtd1 * dT - - k1 = W \ linsolve_tmp - u = uprev + a21 * k1 - du = f(u, p, t + c2 * dt) - - linsolve_tmp = du + dtd2 * dT + dtC21 * k1 - - k2 = W \ linsolve_tmp - u = uprev + a31 * k1 + a32 * k2 - du = f(u, p, t + c3 * dt) - - linsolve_tmp = du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - - k3 = W \ linsolve_tmp - u = uprev + a41 * k1 + a42 * k2 + a43 * k3 - du = f(u, p, t + c4 * dt) - - linsolve_tmp = du + dtd4 * dT + (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - - k4 = W \ linsolve_tmp - u = uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - du = f(u, p, t + c5 * dt) - - linsolve_tmp = du + dtd5 * dT + (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3) - - k5 = W \ linsolve_tmp - u = uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 - du = f(u, p, t + dt) - - linsolve_tmp = du + (dtC61 * k1 + dtC62 * k2 + dtC63 * k3 + dtC64 * k4 + dtC65 * k5) - - k6 = W \ linsolve_tmp - u = u + k6 - du = f(u, p, t + dt) - - linsolve_tmp = du + - (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + dtC74 * k4 + dtC75 * k5 + - dtC76 * k6) - - k7 = W \ linsolve_tmp - - u = u + k7 - du = f(u, p, t + dt) - - linsolve_tmp = du + - (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + dtC85 * k5 + - dtC86 * k6 + dtC87 * k7) - - k8 = W \ linsolve_tmp - - @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab - k₁ = h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + h26 * k6 + h27 * k7 + - h28 * k8 - k₂ = h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + h36 * k6 + h37 * k7 + - h38 * k8 - k₃ = h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + h45 * k5 + h46 * k6 + h47 * k7 + - h48 * k8 - copyat_or_push!(k, 1, k₁) - copyat_or_push!(k, 2, k₂) - copyat_or_push!(k, 3, k₃) - end - nothing -end - -function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::Rosenbrock5Cache, - always_calc_begin = false, allow_calc_end = true, - force_calc_end = false) - if length(k) < 3 || always_calc_begin - @unpack du, du1, du2, tmp, k1, k2, k3, k4, k5, k6, k7, k8, dT, J, W, uf, tf, linsolve_tmp, jac_config, fsalfirst, weight = cache - @unpack a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, C21, C31, C32, C41, C42, C43, C51, C52, C53, C54, C61, C62, C63, C64, C65, C71, C72, C73, C74, C75, C76, C81, C82, C83, C84, C85, C86, C87, gamma, d1, d2, d3, d4, d5, c2, c3, c4, c5 = cache.tab - - # Assignments - sizeu = size(u) - uidx = eachindex(uprev) - mass_matrix = f.mass_matrix - tmp = k8 # integrator.tmp === linsolve_tmp, aliasing fails due to linsolve mutation - - # Precalculations - dtC21 = C21 / dt - dtC31 = C31 / dt - dtC32 = C32 / dt - dtC41 = C41 / dt - dtC42 = C42 / dt - dtC43 = C43 / dt - dtC51 = C51 / dt - dtC52 = C52 / dt - dtC53 = C53 / dt - dtC54 = C54 / dt - dtC61 = C61 / dt - dtC62 = C62 / dt - dtC63 = C63 / dt - dtC64 = C64 / dt - dtC65 = C65 / dt - dtC71 = C71 / dt - dtC72 = C72 / dt - dtC73 = C73 / dt - dtC74 = C74 / dt - dtC75 = C75 / dt - dtC76 = C76 / dt - dtC81 = C81 / dt - dtC82 = C82 / dt - dtC83 = C83 / dt - dtC84 = C84 / dt - dtC85 = C85 / dt - dtC86 = C86 / dt - dtC87 = C87 / dt - - dtd1 = dt * d1 - dtd2 = dt * d2 - dtd3 = dt * d3 - dtd4 = dt * d4 - dtd5 = dt * d5 - dtgamma = dt * gamma - - @.. broadcast=false linsolve_tmp=@muladd fsalfirst + dtgamma * dT - - ### Jacobian does not need to be re-evaluated after an event - ### Since it's unchanged - jacobian2W!(W, mass_matrix, dtgamma, J, true) - - linsolve = cache.linsolve - - linres = dolinsolve(cache, linsolve; A = W, b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck1 = _vec(k1) - - @.. broadcast=false veck1=-vecu - @.. broadcast=false tmp=uprev + a21 * k1 - f(du, tmp, p, t + c2 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + dtC21 * k1 - else - @.. broadcast=false du1=dtC21 * k1 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd2 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck2 = _vec(k2) - @.. broadcast=false veck2=-vecu - @.. broadcast=false tmp=uprev + a31 * k1 + a32 * k2 - f(du, tmp, p, t + c3 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + (dtC31 * k1 + dtC32 * k2) - else - @.. broadcast=false du1=dtC31 * k1 + dtC32 * k2 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd3 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck3 = _vec(k3) - @.. broadcast=false veck3=-vecu - @.. broadcast=false tmp=uprev + a41 * k1 + a42 * k2 + a43 * k3 - f(du, tmp, p, t + c4 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + - (dtC41 * k1 + dtC42 * k2 + dtC43 * k3) - else - @.. broadcast=false du1=dtC41 * k1 + dtC42 * k2 + dtC43 * k3 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd4 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck4 = _vec(k4) - @.. broadcast=false veck4=-vecu - @.. broadcast=false tmp=uprev + a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4 - f(du, tmp, p, t + c5 * dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + dtd5 * dT + - (dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + - dtC53 * k3) - else - @.. broadcast=false du1=dtC52 * k2 + dtC54 * k4 + dtC51 * k1 + dtC53 * k3 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + dtd5 * dT + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck5 = _vec(k5) - @.. broadcast=false veck5=-vecu - @.. broadcast=false tmp=uprev + a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4 + a65 * k5 - f(du, tmp, p, t + dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC62 * k2 + dtC64 * k4 + dtC61 * k1 + - dtC63 * k3 + dtC65 * k5) - else - @.. broadcast=false du1=dtC62 * k2 + dtC64 * k4 + dtC61 * k1 + dtC63 * k3 + - dtC65 * k5 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck6 = _vec(k6) - @.. broadcast=false veck6=-vecu - @.. broadcast=false tmp+=k6 - f(du, tmp, p, t + dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC71 * k1 + dtC72 * k2 + dtC73 * k3 + - dtC74 * k4 + dtC75 * k5 + dtC76 * k6) - else - @.. broadcast=false du1=dtC72 * k2 + dtC74 * k4 + dtC71 * k1 + dtC73 * k3 + - dtC75 * k5 + dtC76 * k6 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck7 = _vec(k7) - @.. broadcast=false veck7=-vecu - @.. broadcast=false tmp+=k7 - f(du, tmp, p, t + dt) - - if mass_matrix === I - @.. broadcast=false linsolve_tmp=du + (dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + - dtC84 * k4 + dtC85 * k5 + dtC86 * k6 + - dtC87 * k7) - else - @.. broadcast=false du1=dtC81 * k1 + dtC82 * k2 + dtC83 * k3 + dtC84 * k4 + - dtC85 * k5 + dtC86 * k6 + dtC87 * k7 - mul!(du2, mass_matrix, du1) - @.. broadcast=false linsolve_tmp=du + du2 - end - - linres = dolinsolve(cache, linres.cache; b = _vec(linsolve_tmp), - reltol = cache.reltol) - vecu = _vec(linres.u) - veck8 = _vec(k8) - @.. broadcast=false veck8=-vecu - - # https://github.com/SciML/OrdinaryDiffEq.jl/issues/2055 - tmp = linsolve_tmp - - @unpack h21, h22, h23, h24, h25, h26, h27, h28, h31, h32, h33, h34, h35, h36, h37, h38, h41, h42, h43, h44, h45, h46, h47, h48 = cache.tab - @.. broadcast=false tmp=h21 * k1 + h22 * k2 + h23 * k3 + h24 * k4 + h25 * k5 + - h26 * k6 + h27 * k7 + h28 * k8 - copyat_or_push!(k, 1, copy(tmp)) - - @.. broadcast=false tmp=h31 * k1 + h32 * k2 + h33 * k3 + h34 * k4 + h35 * k5 + - h36 * k6 + h37 * k7 + h38 * k8 - copyat_or_push!(k, 2, copy(tmp)) - - @.. broadcast=false tmp=h41 * k1 + h42 * k2 + h43 * k3 + h44 * k4 + h45 * k5 + - h46 * k6 + h47 * k7 + h48 * k8 - copyat_or_push!(k, 3, copy(tmp)) - end - nothing -end diff --git a/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl b/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl deleted file mode 100644 index ce876ae507..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl +++ /dev/null @@ -1,706 +0,0 @@ -using OrdinaryDiffEq, DiffEqDevTools, Test, LinearAlgebra, LinearSolve -import ODEProblemLibrary: prob_ode_linear, - prob_ode_2Dlinear, - prob_ode_bigfloatlinear, prob_ode_bigfloat2Dlinear -import LinearSolve - -@testset "Rosenbrock Tests" begin - ## Breakout these since no other test of their adaptivity - - dts = (1 / 2) .^ (6:-1:3) - testTol = 0.2 - - ### Rosenbrock23() - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Rosenbrock23()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, Rosenbrock23()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rosenbrock23()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, Rosenbrock23()) - @test length(sol) < 20 - - prob = prob_ode_bigfloat2Dlinear - - sim = test_convergence(dts, prob, Rosenbrock23(linsolve = QRFactorization())) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, Rosenbrock23(linsolve = QRFactorization())) - @test length(sol) < 20 - - ### Rosenbrock32() - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Rosenbrock32()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, Rosenbrock32()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rosenbrock32()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, Rosenbrock32()) - @test length(sol) < 20 - - ### ROS3P() - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS3P()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3P()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS3P()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3P()) - @test length(sol) < 20 - - ### Rodas3() - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Rodas3()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, Rodas3()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas3()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, Rodas3()) - @test length(sol) < 20 - - ### ROS2 - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS2()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, ROS2()) - @test length(sol) < 61 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS2()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, ROS2PR()) - @test length(sol) < 60 - - ### ROS2PR - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS2PR()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, ROS2PR()) - @test length(sol) < 30 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS2PR()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, ROS2PR()) - @test length(sol) < 30 - - ### ROS2S - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS2S()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, ROS2S()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS2S()) - @test sim.𝒪est[:final]≈2 atol=testTol - - sol = solve(prob, ROS2S()) - @test length(sol) < 20 - - ### ROS3 - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS3()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS3()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3()) - @test length(sol) < 20 - - ### ROS3PR - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS3PR()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3PR()) - @test length(sol) < 20 #length(sol) = 4 => Too Small?? - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS3PR()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3PR()) - @test length(sol) < 20 #length(sol) = 4 => Too Small?? - - ### Scholz4_7 - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Scholz4_7()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, Scholz4_7()) - @test length(sol) < 30 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Scholz4_7()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, Scholz4_7()) - @test length(sol) < 30 - - println("4th order Rosenbrocks") - - ### RosShamp4 - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, RosShamp4()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, RosShamp4()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, RosShamp4()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, RosShamp4()) - @test length(sol) < 20 - - ### Veldd4 - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Veldd4()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, Veldd4()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Veldd4()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, Veldd4()) - @test length(sol) < 20 - - ### Velds4 - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Velds4()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, Velds4()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Velds4()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, Velds4()) - @test length(sol) < 20 - - ### GRK4T - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, GRK4T()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, GRK4T()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, GRK4T()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, GRK4T()) - @test length(sol) < 20 - - ### GRK4A - dts = (1 / 2) .^ (7:-1:4) - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, GRK4A()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, GRK4A()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, GRK4A()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, GRK4A()) - @test length(sol) < 20 - - ### Ros4LStab - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Ros4LStab()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, Ros4LStab()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Ros4LStab()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, Ros4LStab()) - @test length(sol) < 20 - - ### Rosenbrock-W Algorithms - - println("Rosenbrock-W") - - ### ROS34PW1a - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS34PW1a()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PW1a()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS34PW1a()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PW1a()) - @test length(sol) < 20 - - ### ROS34PW1b - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS34PW1b()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PW1b()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS34PW1b()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PW1b()) - @test length(sol) < 20 - - ### ROS34PW2 - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS34PW2()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PW2()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS34PW2()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PW2()) - @test length(sol) < 20 - - ### ROS34PW3 - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS34PW3()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, ROS34PW3()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS34PW3()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, ROS34PW3()) - @test length(sol) < 20 - - ### ROS34PRw - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS34PRw()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PRw()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS34PRw()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS34PRw()) - @test length(sol) < 20 - - ### ROS3PRL - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS3PRL()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3PRL()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS3PRL()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3PRL()) - @test length(sol) < 20 - - ### ROS3PRL2 - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROS3PRL2()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3PRL2()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROS3PRL2()) - @test sim.𝒪est[:final]≈3 atol=testTol - - sol = solve(prob, ROS3PRL2()) - @test length(sol) < 20 - - ### ROK4a - prob = prob_ode_linear - - sim = test_convergence(dts, prob, ROK4a()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, ROK4a()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, ROK4a()) - @test sim.𝒪est[:final]≈4 atol=testTol - - sol = solve(prob, ROK4a()) - @test length(sol) < 20 - - ### RosenbrockW6S4OS - sim = test_convergence(dts, prob, RosenbrockW6S4OS())#test inplace - @test sim.𝒪est[:final]≈4 atol=testTol - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, RosenbrockW6S4OS())#test non-inplace - @test sim.𝒪est[:final]≈4 atol=testTol - - ### Rodas23W, Rodas3P - - println("Rodas23W") - - prob = prob_ode_linear - - dts = (1 / 2) .^ (6:-1:3) - sim = test_convergence(dts, prob, Rodas23W(), dense_errors = true) - @test sim.𝒪est[:final]≈2 atol=testTol - @test sim.𝒪est[:L2]≈2 atol=testTol - - sol = solve(prob, Rodas23W()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas23W(), dense_errors = true) - @test sim.𝒪est[:final]≈2 atol=testTol - @test sim.𝒪est[:L2]≈2 atol=testTol - - sol = solve(prob, Rodas23W()) - @test length(sol) < 20 - - println("Rodas3P") - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Rodas3P(), dense_errors = true) - @test sim.𝒪est[:final]≈3 atol=testTol - @test sim.𝒪est[:L2]≈3 atol=testTol - - sol = solve(prob, Rodas3P()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas3P(), dense_errors = true) - @test sim.𝒪est[:final]≈3 atol=testTol - @test sim.𝒪est[:L2]≈3 atol=testTol - - sol = solve(prob, Rodas3P()) - @test length(sol) < 20 - - ### Rodas4 Algorithms - - println("RODAS") - - dts = (1 / 2) .^ (7:-1:4) - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Rodas4(), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4()) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas4(autodiff = false), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4(autodiff = false)) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas42(), dense_errors = true) - @test sim.𝒪est[:final]≈5.1 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas42()) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas4P(), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4P()) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas4P2(), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4P2()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas4(), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4()) - @test length(sol) < 20 - - println("Rodas4 with finite diff") - - sim = test_convergence(dts, prob, Rodas4(autodiff = false), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4(autodiff = false)) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas4(autodiff = false, - diff_type = Val{:forward}), - dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4(autodiff = false, diff_type = Val{:forward})) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas4(autodiff = false, - diff_type = Val{:complex}), - dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4(autodiff = false, diff_type = Val{:complex})) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas42(), dense_errors = true) - @test sim.𝒪est[:final]≈5 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas42()) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas4P(), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4P()) - @test length(sol) < 20 - - sim = test_convergence(dts, prob, Rodas4P2(), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4P2()) - @test length(sol) < 20 - - println("Rodas4P2 with finite diff") - - sim = test_convergence(dts, prob, Rodas4P2(autodiff = false), dense_errors = true) - @test sim.𝒪est[:final]≈4 atol=testTol - @test sim.𝒪est[:L2]≈4 atol=testTol - - sol = solve(prob, Rodas4P2(autodiff = false)) - @test length(sol) < 20 - - ### Rodas5 - println("Rodas5") - - prob = prob_ode_linear - - dts = (1 / 2) .^ (6:-1:3) - sim = test_convergence(dts, prob, Rodas5(), dense_errors = true) - @test sim.𝒪est[:final]≈5 atol=testTol - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas5(), dense_errors = true) - @test sim.𝒪est[:final]≈5 atol=testTol - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5()) - @test length(sol) < 20 - - println("Rodas5P") - - prob = prob_ode_linear - - dts = (1 / 2) .^ (5:-1:2) - sim = test_convergence(dts, prob, Rodas5P(), dense_errors = true) - #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5P()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas5P(), dense_errors = true) - #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5P()) - @test length(sol) < 20 - - println("Rodas5Pe") - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Rodas5Pe(), dense_errors = true) - #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5Pe()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas5Pe(), dense_errors = true) - #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5Pe()) - @test length(sol) < 20 - - println("Rodas5Pr") - - prob = prob_ode_linear - - sim = test_convergence(dts, prob, Rodas5Pr(), dense_errors = true) - #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5Pr()) - @test length(sol) < 20 - - prob = prob_ode_2Dlinear - - sim = test_convergence(dts, prob, Rodas5Pr(), dense_errors = true) - #@test sim.𝒪est[:final]≈5 atol=testTol #-- observed order > 6 - @test sim.𝒪est[:L2]≈5 atol=testTol - - sol = solve(prob, Rodas5Pr()) - @test length(sol) < 20 - - prob = ODEProblem((u, p, t) -> 0.9u, 0.1, (0.0, 1.0)) - @test_nowarn solve(prob, Rosenbrock23(autodiff = false)) -end - -@testset "Convergence with time-dependent matrix-free Jacobian" begin - time_derivative(du, u, p, t) = (du[1] = t * u[1]) - time_derivative_analytic(u0, p, t) = u0 * exp(t^2 / 2) - ff_time_derivative = ODEFunction(time_derivative, analytic = time_derivative_analytic) - prob = ODEProblem(ff_time_derivative, [1.0], (0.0, 1.0)) - - dts = (1 / 2) .^ (6:-1:3) - testTol = 0.2 - # Check convergence of Rodas3 with time-dependent matrix-free Jacobian. - # Primarily to check that the Jacobian is being updated correctly as t changes. - sim = test_convergence(dts, prob, Rodas3(linsolve = LinearSolve.KrylovJL())) - @test sim.𝒪est[:final]≈3 atol=testTol -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqRosenbrock/test/runtests.jl b/lib/OrdinaryDiffEqRosenbrock/test/runtests.jl deleted file mode 100644 index 75f8efa4f4..0000000000 --- a/lib/OrdinaryDiffEqRosenbrock/test/runtests.jl +++ /dev/null @@ -1,3 +0,0 @@ -using SafeTestsets - -@time @safetestset "Rosenbrock Tests" include("ode_rosenbrock_tests.jl") \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml deleted file mode 100644 index dd466e9602..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ /dev/null @@ -1,22 +0,0 @@ -name = "OrdinaryDiffEqSDIRK" -uuid = "b2cb2727-2d56-444c-bf6a-1484cae16977" -authors = ["ParamThakkar123 "] -version = "1.0.0" - -[deps] -FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" - -[compat] -julia = "1.10" - -[extras] -DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" -Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl deleted file mode 100644 index 8272f5a9ae..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ /dev/null @@ -1,2 +0,0 @@ -module OrdinaryDiffEqSDIRK -end diff --git a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl deleted file mode 100644 index 384dd7dea8..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl +++ /dev/null @@ -1,47 +0,0 @@ -alg_extrapolates(alg::SDIRK22) = true -alg_extrapolates(alg::ImplicitEuler) = true -alg_extrapolates(alg::Trapezoid) = true - -alg_adaptive_order(alg::ImplicitEuler) = 0 -alg_adaptive_order(alg::ImplicitMidpoint) = 1 -alg_adaptive_order(alg::Trapezoid) = 1 - -alg_order(alg::TRBDF2) = 2 -alg_order(alg::ImplicitEuler) = 1 -alg_order(alg::Trapezoid) = 2 -alg_order(alg::ImplicitMidpoint) = 2 -alg_order(alg::SSPSDIRK2) = 2 -alg_order(alg::KenCarp3) = 3 -alg_order(alg::CFNLIRK3) = 3 -alg_order(alg::SDIRK2) = 2 -alg_order(alg::SDIRK22) = 2 -alg_order(alg::ESDIRK54I8L2SA) = 5 -alg_order(alg::ESDIRK436L2SA2) = 4 -alg_order(alg::ESDIRK437L2SA) = 4 -alg_order(alg::Kvaerno3) = 3 -alg_order(alg::ESDIRK547L2SA2) = 5 -alg_order(alg::ESDIRK659L2SA) = 6 -alg_order(alg::SFSDIRK4) = 4 -alg_order(alg::SFSDIRK5) = 4 -alg_order(alg::SFSDIRK6) = 4 -alg_order(alg::SFSDIRK7) = 4 -alg_order(alg::SFSDIRK8) = 4 -alg_order(alg::Cash4) = 4 -alg_order(alg::Hairer4) = 4 -alg_order(alg::Hairer42) = 4 -alg_order(alg::Kvaerno4) = 4 -alg_order(alg::Kvaerno5) = 5 -alg_order(alg::KenCarp4) = 4 -alg_order(alg::KenCarp47) = 4 -alg_order(alg::KenCarp5) = 5 -alg_order(alg::KenCarp58) = 5 - -ssp_coefficient(alg::SSPSDIRK2) = 4 - -isesdirk(alg::TRBDF2) = true -function isesdirk(alg::Union{KenCarp3, KenCarp4, KenCarp5, KenCarp58, - Kvaerno3, Kvaerno4, Kvaerno5, ESDIRK437L2SA, - ESDIRK54I8L2SA, ESDIRK436L2SA2, ESDIRK547L2SA2, - ESDIRK659L2SA, CFNLIRK3}) - true -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl deleted file mode 100644 index 2442b77ad5..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl +++ /dev/null @@ -1,864 +0,0 @@ -# SDIRK Methods -""" -ImplicitEuler: SDIRK Method -A 1st order implicit solver. A-B-L-stable. Adaptive timestepping through a divided differences estimate via memory. -Strong-stability preserving (SSP). -""" -struct ImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function ImplicitEuler(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :PI, step_limiter! = trivial_limiter!) - ImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, precs, extrapolant, controller, step_limiter!) -end - -""" -ImplicitMidpoint: SDIRK Method -A second order A-stable symplectic and symmetric implicit solver. -Good for highly stiff equations which need symplectic integration. -""" -struct ImplicitMidpoint{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - step_limiter!::StepLimiter -end - -function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, step_limiter! = trivial_limiter!) - ImplicitMidpoint{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - step_limiter!) -end - -""" -Andre Vladimirescu. 1994. The Spice Book. John Wiley & Sons, Inc., New York, -NY, USA. - -Trapezoid: SDIRK Method -A second order A-stable symmetric ESDIRK method. -"Almost symplectic" without numerical dampening. -Also known as Crank-Nicolson when applied to PDEs. Adaptive timestepping via divided -differences approximation to the second derivative terms in the local truncation error -estimate (the SPICE approximation strategy). -""" -struct Trapezoid{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function Trapezoid(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - controller, - step_limiter!) -end - -""" -@article{hosea1996analysis, -title={Analysis and implementation of TR-BDF2}, -author={Hosea, ME and Shampine, LF}, -journal={Applied Numerical Mathematics}, -volume={20}, -number={1-2}, -pages={21--37}, -year={1996}, -publisher={Elsevier} -} - -TRBDF2: SDIRK Method -A second order A-B-L-S-stable one-step ESDIRK method. -Includes stiffness-robust error estimates for accurate adaptive timestepping, smoothed derivatives for highly stiff and oscillatory problems. -""" -struct TRBDF2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function TRBDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - TRBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace TRBDF2 - -""" -@article{hindmarsh2005sundials, -title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, -author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, -journal={ACM Transactions on Mathematical Software (TOMS)}, -volume={31}, -number={3}, -pages={363--396}, -year={2005}, -publisher={ACM} -} - -SDIRK2: SDIRK Method -An A-B-L stable 2nd order SDIRK method -""" -struct SDIRK2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function SDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - SDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}( - linsolve, nlsolve, precs, smooth_est, extrapolant, - controller, - step_limiter!) -end - -struct SDIRK22{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function SDIRK22(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - controller, - step_limiter!) -end - -struct SSPSDIRK2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} # Not adaptive - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end - -function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :constant, - controller = :PI) - SSPSDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno3: SDIRK Method -An A-L stable stiffly-accurate 3rd order ESDIRK method -""" -struct Kvaerno3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp3: SDIRK Method -An A-L stable stiffly-accurate 3rd order ESDIRK method with splitting -""" -struct KenCarp3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -struct CFNLIRK3{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function CFNLIRK3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - CFNLIRK3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -""" -@article{hindmarsh2005sundials, -title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, -author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, -journal={ACM Transactions on Mathematical Software (TOMS)}, -volume={31}, -number={3}, -pages={363--396}, -year={2005}, -publisher={ACM} -} - -Cash4: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Cash4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - embedding::Int - controller::Symbol -end -function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, embedding = 3) - Cash4{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( - linsolve, - nlsolve, - precs, - smooth_est, - extrapolant, - embedding, - controller) -end - -struct SFSDIRK4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function SFSDIRK4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK5{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK6{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK6(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK6{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK7{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK7(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK7{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK8{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK8(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK8{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -""" -E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and -differential-algebraic problems. Computational mathematics (2nd revised ed.), -Springer (1996) - -Hairer4: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Hairer4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function Hairer4(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - Hairer4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and -differential-algebraic problems. Computational mathematics (2nd revised ed.), -Springer (1996) - -Hairer42: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Hairer42{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function Hairer42(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - Hairer42{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno4: SDIRK Method -An A-L stable stiffly-accurate 4th order ESDIRK method. -""" -struct Kvaerno4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno5: SDIRK Method -An A-L stable stiffly-accurate 5th order ESDIRK method -""" -struct Kvaerno5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp4: SDIRK Method -An A-L stable stiffly-accurate 4th order ESDIRK method with splitting -""" -struct KenCarp4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace KenCarp4 - -""" -@article{kennedy2019higher, -title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, -author={Kennedy, Christopher A and Carpenter, Mark H}, -journal={Applied Numerical Mathematics}, -volume={136}, -pages={183--205}, -year={2019}, -publisher={Elsevier} -} - -KenCarp47: SDIRK Method -An A-L stable stiffly-accurate 4th order seven-stage ESDIRK method with splitting -""" -struct KenCarp47{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function KenCarp47(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - KenCarp47{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp5: SDIRK Method -An A-L stable stiffly-accurate 5th order ESDIRK method with splitting -""" -struct KenCarp5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@article{kennedy2019higher, -title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, -author={Kennedy, Christopher A and Carpenter, Mark H}, -journal={Applied Numerical Mathematics}, -volume={136}, -pages={183--205}, -year={2019}, -publisher={Elsevier} -} - -KenCarp58: SDIRK Method -An A-L stable stiffly-accurate 5th order eight-stage ESDIRK method with splitting -""" -struct KenCarp58{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function KenCarp58(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - KenCarp58{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -# `smooth_est` is not necessary, as the embedded method is also L-stable -struct ESDIRK54I8L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK54I8L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK436L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK436L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK437L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK437L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK547L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK547L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} - -Currently has STABILITY ISSUES, causing it to fail the adaptive tests. -Check issue https://github.com/SciML/OrdinaryDiffEq.jl/issues/1933 for more details. -} -""" -struct ESDIRK659L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK659L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl deleted file mode 100644 index 0af6130b8b..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl +++ /dev/null @@ -1,642 +0,0 @@ -mutable struct Kvaerno3ConstantCache{Tab, N} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::Kvaerno3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Kvaerno3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, 2tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - Kvaerno3ConstantCache(nlsolver, tab) -end - -@cache mutable struct Kvaerno3Cache{uType, rateType, uNoUnitsType, Tab, N, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -function alg_cache(alg::Kvaerno3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Kvaerno3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, 2tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - Kvaerno3Cache( - u, uprev, fsalfirst, z₁, z₂, z₃, z₄, atmp, nlsolver, tab, alg.step_limiter!) -end - -@cache mutable struct KenCarp3ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::KenCarp3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - KenCarp3ConstantCache(nlsolver, tab) -end - -@cache mutable struct KenCarp3Cache{ - uType, rateType, uNoUnitsType, N, Tab, kType, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - k1::kType - k2::kType - k3::kType - k4::kType - atmp::uNoUnitsType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -function alg_cache(alg::KenCarp3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - if f isa SplitFunction - k1 = zero(u) - k2 = zero(u) - k3 = zero(u) - k4 = zero(u) - else - k1 = nothing - k2 = nothing - k3 = nothing - k4 = nothing - uf = UJacobianWrapper(f, t, p) - end - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - KenCarp3Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, k1, k2, - k3, k4, atmp, nlsolver, tab, alg.step_limiter!) -end - -@cache mutable struct CFNLIRK3ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::CFNLIRK3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = CFNLIRK3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - CFNLIRK3ConstantCache(nlsolver, tab) -end - -@cache mutable struct CFNLIRK3Cache{uType, rateType, uNoUnitsType, N, Tab, kType} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - k1::kType - k2::kType - k3::kType - k4::kType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::CFNLIRK3, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = CFNLIRK3Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - k1 = zero(u) - k2 = zero(u) - k3 = zero(u) - k4 = zero(u) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - CFNLIRK3Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, k1, k2, k3, k4, atmp, nlsolver, tab) -end - -@cache mutable struct Kvaerno4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::Kvaerno4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Kvaerno4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - Kvaerno4ConstantCache(nlsolver, tab) -end - -@cache mutable struct Kvaerno4Cache{uType, rateType, uNoUnitsType, N, Tab, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -function alg_cache(alg::Kvaerno4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Kvaerno4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - Kvaerno4Cache( - u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab, alg.step_limiter!) -end - -@cache mutable struct KenCarp4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::KenCarp4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - KenCarp4ConstantCache(nlsolver, tab) -end - -@cache mutable struct KenCarp4Cache{ - uType, rateType, uNoUnitsType, N, Tab, kType, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - k1::kType - k2::kType - k3::kType - k4::kType - k5::kType - k6::kType - atmp::uNoUnitsType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -TruncatedStacktraces.@truncate_stacktrace KenCarp4Cache 1 - -function alg_cache(alg::KenCarp4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - if f isa SplitFunction - k1 = zero(u) - k2 = zero(u) - k3 = zero(u) - k4 = zero(u) - k5 = zero(u) - k6 = zero(u) - else - k1 = nothing - k2 = nothing - k3 = nothing - k4 = nothing - k5 = nothing - k6 = nothing - uf = UJacobianWrapper(f, t, p) - end - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - KenCarp4Cache( - u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, k1, k2, k3, k4, k5, k6, atmp, - nlsolver, tab, alg.step_limiter!) -end - -@cache mutable struct Kvaerno5ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::Kvaerno5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Kvaerno5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - Kvaerno5ConstantCache(nlsolver, tab) -end - -@cache mutable struct Kvaerno5Cache{uType, rateType, uNoUnitsType, N, Tab, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -function alg_cache(alg::Kvaerno5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Kvaerno5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - Kvaerno5Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, - z₇, atmp, nlsolver, tab, alg.step_limiter!) -end - -@cache mutable struct KenCarp5ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::KenCarp5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - KenCarp5ConstantCache(nlsolver, tab) -end - -@cache mutable struct KenCarp5Cache{ - uType, rateType, uNoUnitsType, N, Tab, kType, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - z₈::uType - k1::kType - k2::kType - k3::kType - k4::kType - k5::kType - k6::kType - k7::kType - k8::kType - atmp::uNoUnitsType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -function alg_cache(alg::KenCarp5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - if f isa SplitFunction - k1 = zero(u) - k2 = zero(u) - k3 = zero(u) - k4 = zero(u) - k5 = zero(u) - k6 = zero(u) - k7 = zero(u) - k8 = zero(u) - else - k1 = nothing - k2 = nothing - k3 = nothing - k4 = nothing - k5 = nothing - k6 = nothing - k7 = nothing - k8 = nothing - end - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = zero(u) - z₈ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - KenCarp5Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, - k1, k2, k3, k4, k5, k6, k7, k8, atmp, nlsolver, tab, alg.step_limiter!) -end - -@cache mutable struct KenCarp47ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::KenCarp47, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp47Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - KenCarp47ConstantCache(nlsolver, tab) -end - -@cache mutable struct KenCarp47Cache{uType, rateType, uNoUnitsType, N, Tab, kType} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - k1::kType - k2::kType - k3::kType - k4::kType - k5::kType - k6::kType - k7::kType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end -TruncatedStacktraces.@truncate_stacktrace KenCarp47Cache 1 - -function alg_cache(alg::KenCarp47, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp47Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - if f isa SplitFunction - k1 = zero(u) - k2 = zero(u) - k3 = zero(u) - k4 = zero(u) - k5 = zero(u) - k6 = zero(u) - k7 = zero(u) - else - k1 = nothing - k2 = nothing - k3 = nothing - k4 = nothing - k5 = nothing - k6 = nothing - k7 = nothing - end - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - KenCarp47Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, - k1, k2, k3, k4, k5, k6, k7, atmp, nlsolver, tab) -end - -@cache mutable struct KenCarp58ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::KenCarp58, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp58Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - KenCarp58ConstantCache(nlsolver, tab) -end - -@cache mutable struct KenCarp58Cache{uType, rateType, uNoUnitsType, N, Tab, kType} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - z₈::uType - k1::kType - k2::kType - k3::kType - k4::kType - k5::kType - k6::kType - k7::kType - k8::kType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -TruncatedStacktraces.@truncate_stacktrace KenCarp58Cache 1 - -function alg_cache(alg::KenCarp58, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = KenCarp58Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.c3 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - if f isa SplitFunction - k1 = zero(u) - k2 = zero(u) - k3 = zero(u) - k4 = zero(u) - k5 = zero(u) - k6 = zero(u) - k7 = zero(u) - k8 = zero(u) - else - k1 = nothing - k2 = nothing - k3 = nothing - k4 = nothing - k5 = nothing - k6 = nothing - k7 = nothing - k8 = nothing - end - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = zero(u) - z₈ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - KenCarp58Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, - k1, k2, k3, k4, k5, k6, k7, k8, atmp, nlsolver, tab) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl deleted file mode 100644 index bd43f4faea..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl +++ /dev/null @@ -1,2665 +0,0 @@ -function initialize!(integrator, - cache::Union{Kvaerno3ConstantCache, - KenCarp3ConstantCache, - Kvaerno4ConstantCache, - KenCarp4ConstantCache, - KenCarp47ConstantCache, - Kvaerno5ConstantCache, - KenCarp5ConstantCache, - KenCarp58ConstantCache, - CFNLIRK3ConstantCache - }) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function initialize!(integrator, - cache::Union{Kvaerno3Cache, - KenCarp3Cache, - Kvaerno4Cache, - KenCarp4Cache, - Kvaerno5Cache, - KenCarp5Cache, - CFNLIRK3Cache, - KenCarp47Cache, - KenCarp58Cache - }) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::Kvaerno3ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32 = cache.tab - alg = unwrap_alg(integrator, true) - - # calculate W - markfirststage!(nlsolver) - - # FSAL Step 1 - nlsolver.z = z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation for guess - nlsolver.z = z₂ = z₁ - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess is from Hermite derivative on z₁ and z₂ - nlsolver.z = z₃ = α31 * z₁ + α32 * z₂ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = a31 * z₁ + a32 * z₂ + γ * z₃ # use yhat as prediction - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = 1 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₄ - - ################################### Finalize - - if integrator.opts.adaptive - tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₄ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::Kvaerno3Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, atmp, nlsolver, step_limiter! = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - # FSAL Step 1 - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation for guess - copyto!(z₂, z₁) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - # Guess is from Hermite derivative on z₁ and z₂ - @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ - nlsolver.z = z₃ - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if cache isa Kvaerno3Cache - @.. broadcast=false z₄=a31 * z₁ + a32 * z₂ + γ * z₃ # use yhat as prediction - elseif cache isa KenCarp3Cache - @unpack α41, α42 = cache.tab - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ - end - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = 1 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₄ - - step_limiter!(u, integrator, p, t + dt) - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₄ / dt -end - -@muladd function perform_step!(integrator, cache::KenCarp3ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4, ebtilde1, ebtilde2, ebtilde3, ebtilde4 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - if integrator.f isa SplitFunction - # Explicit tableau is not FSAL - # Make this not compute on repeat - z₁ = dt * f(uprev, p, t) - else - # FSAL Step 1 - z₁ = dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation for guess - nlsolver.z = z₂ = z₁ - - nlsolver.tmp = uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - k1 = dt * integrator.fsalfirst - z₁ - nlsolver.tmp += ea21 * k1 - end - - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ = z₂ - u = nlsolver.tmp + γ * z₂ - k2 = dt * f2(u, p, t + 2γdt) - integrator.stats.nf2 += 1 - tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - z₃ = α31 * z₁ + α32 * z₂ - tmp = uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - nlsolver.tmp = tmp - nlsolver.c = c3 - - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ = z₂ - u = nlsolver.tmp + γ * z₃ - k3 = dt * f2(u, p, t + c3 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 - else - @unpack α41, α42 = cache.tab - z₄ = α41 * z₁ + α42 * z₂ - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - nlsolver.c = 1 - nlsolver.tmp = tmp - - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₄ - if integrator.f isa SplitFunction - k4 = dt * f2(u, p, t + dt) - integrator.stats.nf2 += 1 - u = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + eb2 * k2 + - eb3 * k3 + eb4 * k4 - end - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - ebtilde1 * k1 + ebtilde2 * k2 + ebtilde3 * k3 + ebtilde4 * k4 - else - tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ - end - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.k[1] = integrator.fsalfirst - integrator.fsallast = integrator.f(u, p, t + dt) - integrator.k[2] = integrator.fsallast - else - integrator.fsallast = z₄ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - end - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::KenCarp3Cache, repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - @unpack z₁, z₂, z₃, z₄, k1, k2, k3, k4, atmp, nlsolver, step_limiter! = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, α32 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4 = cache.tab - @unpack ebtilde1, ebtilde2, ebtilde3, ebtilde4 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail - # Explicit tableau is not FSAL - # Make this not compute on repeat - f(z₁, integrator.uprev, p, integrator.t) - z₁ .*= dt - else - # FSAL Step 1 - @.. broadcast=false z₁=dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation for guess - copyto!(z₂, z₁) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ - @.. broadcast=false tmp+=ea21 * k1 - end - - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ .= z₂ - @.. broadcast=false u=tmp + γ * z₂ - f2(k2, u, p, t + 2γdt) - k2 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ .= z₂ - @.. broadcast=false u=tmp + γ * z₃ - f2(k3, u, p, t + c3 * dt) - k3 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + - ea42 * k2 + ea43 * k3 - else - @unpack α41, α42 = cache.tab - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - - nlsolver.c = 1 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₄ - if integrator.f isa SplitFunction - f2(k4, u, p, t + dt) - k4 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false u=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + - eb2 * k2 + eb3 * k3 + eb4 * k4 - end - - step_limiter!(u, integrator, p, t + dt) - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + - btilde4 * z₄ + ebtilde1 * k1 + ebtilde2 * k2 + - ebtilde3 * k3 + ebtilde4 * k4 - else - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + - btilde4 * z₄ - end - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.f(integrator.fsallast, u, p, t + dt) - else - @.. broadcast=false integrator.fsallast=z₄ / dt - end -end - -@muladd function perform_step!(integrator, cache::CFNLIRK3ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, c2, c3, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - if integrator.f isa SplitFunction - # Explicit tableau is not FSAL - # Make this not compute on repeat - z₁ = dt .* f(uprev, p, t) - else - # FSAL Step 1 - z₁ = dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation for guess - nlsolver.z = z₂ = z₁ - - nlsolver.tmp = uprev - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - k1 = dt .* f2(uprev, p, t) - nlsolver.tmp += ea21 * k1 - end - - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ = z₂ - u = nlsolver.tmp + γ * z₂ - k2 = dt * f2(u, p, t + c2 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - z₃ = z₂ - tmp = uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - nlsolver.tmp = tmp - nlsolver.c = c3 - - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ = z₃ - u = nlsolver.tmp + γ * z₃ - k3 = dt * f2(u, p, t + c3 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 - else - z₄ = z₃ - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - nlsolver.c = 1 - nlsolver.tmp = tmp - - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₄ - if integrator.f isa SplitFunction - k4 = dt * f2(u, p, t + dt) - integrator.stats.nf2 += 1 - u = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + eb2 * k2 + - eb3 * k3 + eb4 * k4 - end - - ################################### Finalize - - if integrator.f isa SplitFunction - integrator.k[1] = integrator.fsalfirst - integrator.fsallast = integrator.f(u, p, t + dt) - integrator.k[2] = integrator.fsallast - else - integrator.fsallast = z₄ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - end - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::CFNLIRK3Cache, repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - @unpack z₁, z₂, z₃, z₄, k1, k2, k3, k4, atmp, nlsolver = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a42, a43, c2, c3 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4 = cache.tab - - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail - f(z₁, integrator.uprev, p, integrator.t) - z₁ .*= dt - else - # FSAL Step 1 - @.. broadcast=false z₁=dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation for guess - copyto!(z₂, z₁) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ - @.. broadcast=false tmp+=ea21 * k1 - end - - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ .= z₂ - @.. broadcast=false u=tmp + γ * z₂ - f2(k2, u, p, t + c2 * dt) - k2 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - @.. broadcast=false z₃=z₂ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ .= z₂ - @.. broadcast=false u=tmp + γ * z₃ - f2(k3, u, p, t + c3 * dt) - k3 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + - ea42 * k2 + ea43 * k3 - else - @.. broadcast=false z₄=z₂ - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - - nlsolver.c = 1 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₄ - if integrator.f isa SplitFunction - f2(k4, u, p, t + dt) - k4 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false u=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ + eb1 * k1 + - eb2 * k2 + eb3 * k3 + eb4 * k4 - end - - if integrator.f isa SplitFunction - integrator.f(integrator.fsallast, u, p, t + dt) - else - @.. broadcast=false integrator.fsallast=z₄ / dt - end -end - -@muladd function perform_step!(integrator, cache::Kvaerno4ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, c3, c4 = cache.tab - @unpack α21, α31, α32, α41, α42 = cache.tab - @unpack btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - ##### Step 1 - - z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = zero(u) - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - nlsolver.z = z₃ = α31 * z₁ + α32 * z₂ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = α41 * z₁ + α42 * z₂ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use yhat2 for prediction - nlsolver.z = z₅ = a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = 1 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₄ - - ################################### Finalize - - if integrator.opts.adaptive - tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₅ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::Kvaerno4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, step_limiter! = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, c3, c4 = cache.tab - @unpack α21, α31, α32, α41, α42 = cache.tab - @unpack btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - ##### Step 1 - - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Allow other choices here - z₂ .= zero(eltype(u)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ - nlsolver.z = z₃ - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use yhat prediction - @.. broadcast=false z₅=a41 * z₁ + a42 * z₂ + a43 * z₃ + γ * z₄ - nlsolver.z = z₅ - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = 1 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₅ - - step_limiter!(u, integrator, p, t + dt) - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₅ / dt -end - -@muladd function perform_step!(integrator, cache::KenCarp4ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c3, c4, c5 = cache.tab - @unpack α31, α32, α41, α42, α51, α52, α53, α54, α61, α62, α63, α64, α65 = cache.tab - @unpack btilde1, btilde3, btilde4, btilde5, btilde6 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab - @unpack eb1, eb3, eb4, eb5, eb6 = cache.tab - @unpack ebtilde1, ebtilde3, ebtilde4, ebtilde5, ebtilde6 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - if integrator.f isa SplitFunction - # Explicit tableau is not FSAL - # Make this not compute on repeat - z₁ = dt .* f(uprev, p, t) - else - # FSAL Step 1 - z₁ = dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = z₁ - - tmp = uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - k1 = dt * integrator.fsalfirst - z₁ - tmp += ea21 * k1 - end - nlsolver.tmp = tmp - nlsolver.c = 2γ - - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ = z₂ - u = nlsolver.tmp + γ * z₂ - k2 = dt * f2(u, p, t + 2γdt) - integrator.stats.nf2 += 1 - tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - z₃ = α31 * z₁ + α32 * z₂ - tmp = uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - nlsolver.tmp = tmp - nlsolver.c = c3 - - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ = z₂ - u = nlsolver.tmp + γ * z₃ - k3 = dt * f2(u, p, t + c3 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 - else - z₄ = α41 * z₁ + α42 * z₂ - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - nlsolver.tmp = tmp - nlsolver.c = c4 - - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ = z₄ - u = nlsolver.tmp + γ * z₄ - k4 = dt * f2(u, p, t + c4 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea52 * k2 + - ea53 * k3 + ea54 * k4 - else - z₅ = α51 * z₁ + α52 * z₂ + α53 * z₃ + α54 * z₄ - tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - nlsolver.tmp = tmp - nlsolver.c = c5 - - u = nlsolver.tmp + γ * z₅ - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ = z₅ - u = nlsolver.tmp + γ * z₅ - k5 = dt * f2(u, p, t + c5 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + ea62 * k2 + - ea63 * k3 + ea64 * k4 + ea65 * k5 - else - z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ + α64 * z₄ + α65 * z₅ - tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - nlsolver.tmp = tmp - nlsolver.c = 1 - - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₆ - if integrator.f isa SplitFunction - k6 = dt * f2(u, p, t + dt) - integrator.stats.nf2 += 1 - u = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ + eb1 * k1 + - eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 - end - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - tmp = btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + - ebtilde1 * k1 + ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + - ebtilde6 * k6 - else - tmp = btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ - end - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.k[1] = integrator.fsalfirst - integrator.fsallast = integrator.f(u, p, t + dt) - integrator.k[2] = integrator.fsallast - else - integrator.fsallast = z₆ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - end - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::KenCarp4Cache, repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, step_limiter! = cache - @unpack tmp = nlsolver - @unpack k1, k2, k3, k4, k5, k6 = cache - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, c3, c4, c5 = cache.tab - @unpack α31, α32, α41, α42, α51, α52, α53, α54, α61, α62, α63, α64, α65 = cache.tab - @unpack btilde1, btilde3, btilde4, btilde5, btilde6 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab - @unpack eb1, eb3, eb4, eb5, eb6 = cache.tab - @unpack ebtilde1, ebtilde3, ebtilde4, ebtilde5, ebtilde6 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - ##### Step 1 - - if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail - # Explicit tableau is not FSAL - # Make this not compute on repeat - f(z₁, integrator.uprev, p, integrator.t) - z₁ .*= dt - else - # FSAL Step 1 - @.. broadcast=false z₁=dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Allow other choices here - copyto!(z₂, z₁) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ - @.. broadcast=false tmp+=ea21 * k1 - end - - nlsolver.c = 2γ - markfirststage!(nlsolver) - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ .= z₂ - @.. broadcast=false u=tmp + γ * z₂ - f2(k2, u, p, t + 2γdt) - k2 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ .= z₂ - @.. broadcast=false u=tmp + γ * z₃ - f2(k3, u, p, t + c3 * dt) - k3 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + - ea42 * k2 + ea43 * k3 - else - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ .= z₄ - @.. broadcast=false u=tmp + γ * z₄ - f2(k4, u, p, t + c4 * dt) - k4 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + - ea51 * k1 + ea52 * k2 + ea53 * k3 + ea54 * k4 - else - @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ + α53 * z₃ + α54 * z₄ - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ .= z₅ - @.. broadcast=false u=tmp + γ * z₅ - f2(k5, u, p, t + c5 * dt) - k5 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + - ea61 * k1 + ea62 * k2 + ea63 * k3 + ea64 * k4 + ea65 * k5 - else - @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ + α64 * z₄ + α65 * z₅ - @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - - nlsolver.c = 1 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₆ - if integrator.f isa SplitFunction - f2(k6, u, p, t + dt) - k6 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false u=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ + - eb1 * k1 + eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 - end - - step_limiter!(u, integrator, p, t + dt) - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - @.. broadcast=false tmp=btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ + btilde6 * z₆ + ebtilde1 * k1 + - ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + - ebtilde6 * k6 - else - @.. broadcast=false tmp=btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ + btilde6 * z₆ - end - - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.f(integrator.fsallast, u, p, t + dt) - else - @.. broadcast=false integrator.fsallast=z₆ / dt - end -end - -@muladd function perform_step!(integrator, cache::Kvaerno5ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab - @unpack btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - @unpack α31, α32, α41, α42, α43, α51, α52, α53, α61, α62, α63 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - ##### Step 1 - - z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = z₁ - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - nlsolver.z = z₃ = α31 * z₁ + α32 * z₂ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = α41 * z₁ + α42 * z₂ + α43 * z₃ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = z₅ = α51 * z₁ + α52 * z₂ + α53 * z₃ - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ - - nlsolver.tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - # Prediction from embedding - nlsolver.z = z₇ = a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ - - nlsolver.tmp = uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = 1 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₇ - - ################################### Finalize - - if integrator.opts.adaptive - tmp = btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + - btilde7 * z₇ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₇ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::Kvaerno5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, step_limiter! = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab - @unpack btilde1, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - @unpack α31, α32, α41, α42, α43, α51, α52, α53, α61, α62, α63 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - ##### Step 1 - - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Allow other choices here - copyto!(z₂, z₁) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ - nlsolver.z = z₃ - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + α43 * z₃ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ + α53 * z₃ - nlsolver.z = z₅ - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ - nlsolver.z = z₆ - - @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - # Prediction is embedded method - @.. broadcast=false z₇=a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + γ * z₆ - nlsolver.z = z₇ - - @.. broadcast=false tmp=uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = 1 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₇ - - step_limiter!(u, integrator, p, t + dt) - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₇ / dt -end - -@muladd function perform_step!(integrator, cache::KenCarp5ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab - @unpack α31, α32, α41, α42, α51, α52, α61, α62, α71, α72, α73, α74, α75, α81, α82, α83, α84, α85 = cache.tab - @unpack btilde1, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea43, ea51, ea53, ea54, ea61, ea63, ea64, ea65 = cache.tab - @unpack ea71, ea73, ea74, ea75, ea76, ea81, ea83, ea84, ea85, ea86, ea87 = cache.tab - @unpack eb1, eb4, eb5, eb6, eb7, eb8 = cache.tab - @unpack ebtilde1, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - ##### Step 1 - - if integrator.f isa SplitFunction - # Explicit tableau is not FSAL - # Make this not compute on repeat - z₁ = dt .* f(uprev, p, t) - else - # FSAL Step 1 - z₁ = dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = z₁ - - tmp = uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - k1 = dt * integrator.fsalfirst - z₁ - tmp += ea21 * k1 - end - nlsolver.tmp = tmp - nlsolver.c = 2γ - - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ = z₂ - u = nlsolver.tmp + γ * z₂ - k2 = dt * f2(u, p, t + 2γdt) - integrator.stats.nf2 += 1 - tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - z₃ = α31 * z₁ + α32 * z₂ - tmp = uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - nlsolver.c = c3 - nlsolver.tmp = tmp - - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ = z₂ - u = nlsolver.tmp + γ * z₃ - k3 = dt * f2(u, p, t + c3 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a41 * z₁ + a43 * z₃ + ea41 * k1 + ea43 * k3 - else - z₄ = α41 * z₁ + α42 * z₂ - tmp = uprev + a41 * z₁ + a43 * z₃ - end - nlsolver.z = z₄ - nlsolver.c = c4 - nlsolver.tmp = tmp - - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ = z₂ - u = nlsolver.tmp + γ * z₄ - k4 = dt * f2(u, p, t + c4 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea53 * k3 + ea54 * k4 - else - z₅ = α51 * z₁ + α52 * z₂ - tmp = uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - nlsolver.c = c5 - nlsolver.tmp = tmp - - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ = z₃ - u = nlsolver.tmp + γ * z₅ - k5 = dt * f2(u, p, t + c5 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + ea63 * k3 + - ea64 * k4 + ea65 * k5 - else - z₆ = α61 * z₁ + α62 * z₂ - tmp = uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - nlsolver.c = c6 - nlsolver.tmp = tmp - - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - if integrator.f isa SplitFunction - z₇ = z₂ - u = nlsolver.tmp + γ * z₆ - k6 = dt * f2(u, p, t + c6 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + ea71 * k1 + - ea73 * k3 + ea74 * k4 + ea75 * k5 + ea76 * k6 - else - z₇ = α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ - tmp = uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - end - nlsolver.z = z₇ - nlsolver.c = c7 - nlsolver.tmp = tmp - - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - if integrator.f isa SplitFunction - z₈ = z₅ - u = nlsolver.tmp + γ * z₇ - k7 = dt * f2(u, p, t + c7 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + ea81 * k1 + - ea83 * k3 + ea84 * k4 + ea85 * k5 + ea86 * k6 + ea87 * k7 - else - z₈ = α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ - tmp = uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ - end - nlsolver.z = z₈ - nlsolver.c = 1 - nlsolver.tmp = tmp - - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₈ - if integrator.f isa SplitFunction - k8 = dt * f2(u, p, t + dt) - integrator.stats.nf2 += 1 - u = uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + γ * z₈ + - eb1 * k1 + eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 + eb8 * k8 - end - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - tmp = btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + - btilde8 * z₈ + ebtilde1 * k1 + ebtilde4 * k4 + ebtilde5 * k5 + - ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 - else - tmp = btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + - btilde8 * z₈ - end - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.k[1] = integrator.fsalfirst - integrator.fsallast = integrator.f(u, p, t + dt) - integrator.k[2] = integrator.fsallast - else - integrator.fsallast = z₈ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - end - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::KenCarp5Cache, repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver, step_limiter! = cache - @unpack k1, k2, k3, k4, k5, k6, k7, k8 = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, a71, a73, a74, a75, a76, a81, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab - @unpack α31, α32, α41, α42, α51, α52, α61, α62, α71, α72, α73, α74, α75, α81, α82, α83, α84, α85 = cache.tab - @unpack btilde1, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea43, ea51, ea53, ea54, ea61, ea63, ea64, ea65 = cache.tab - @unpack ea71, ea73, ea74, ea75, ea76, ea81, ea83, ea84, ea85, ea86, ea87 = cache.tab - @unpack eb1, eb4, eb5, eb6, eb7, eb8 = cache.tab - @unpack ebtilde1, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - ##### Step 1 - - if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail - # Explicit tableau is not FSAL - # Make this not compute on repeat - f(z₁, integrator.uprev, p, integrator.t) - z₁ .*= dt - else - # FSAL Step 1 - @.. broadcast=false z₁=dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Allow other choices here - copyto!(z₂, z₁) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ - @.. broadcast=false tmp+=ea21 * k1 - end - - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ .= z₂ - @.. broadcast=false u=tmp + γ * z₂ - f2(k2, u, p, t + 2γdt) - k2 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - @.. broadcast=false z₃=a31 * z₁ + α32 * z₂ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ .= z₃ - @.. broadcast=false u=tmp + γ * z₃ - f2(k3, u, p, t + c3 * dt) - k3 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a41 * z₁ + a43 * z₃ + ea41 * k1 + ea43 * k3 - else - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ - @.. broadcast=false tmp=uprev + a41 * z₁ + a43 * z₃ - end - nlsolver.z = z₄ - - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ .= z₂ - @.. broadcast=false u=tmp + γ * z₄ - f2(k4, u, p, t + c4 * dt) - k4 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ + ea51 * k1 + - ea53 * k3 + ea54 * k4 - else - @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ - @.. broadcast=false tmp=uprev + a51 * z₁ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ .= z₃ - @.. broadcast=false u=tmp + γ * z₅ - f2(k5, u, p, t + c5 * dt) - k5 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ + - ea61 * k1 + ea63 * k3 + ea64 * k4 + ea65 * k5 - else - @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ - @.. broadcast=false tmp=uprev + a61 * z₁ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - if integrator.f isa SplitFunction - z₇ .= z₂ - @.. broadcast=false u=tmp + γ * z₆ - f2(k6, u, p, t + c6 * dt) - k6 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ + ea71 * k1 + ea73 * k3 + ea74 * k4 + ea75 * k5 + - ea76 * k6 - else - @.. broadcast=false z₇=α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ - @.. broadcast=false tmp=uprev + a71 * z₁ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - end - nlsolver.z = z₇ - - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - if integrator.f isa SplitFunction - z₈ .= z₅ - @.. broadcast=false u=tmp + γ * z₇ - f2(k7, u, p, t + c7 * dt) - k7 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + - a87 * z₇ + ea81 * k1 + ea83 * k3 + ea84 * k4 + ea85 * k5 + - ea86 * k6 + ea87 * k7 - else - @.. broadcast=false z₈=α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ - @.. broadcast=false tmp=uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ - end - nlsolver.z = z₈ - - nlsolver.c = 1 - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₈ - if integrator.f isa SplitFunction - f2(k8, u, p, t + dt) - k8 .*= dt - integrator.stats.nf += 1 - @.. broadcast=false u=uprev + a81 * z₁ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + - γ * z₈ + eb1 * k1 + eb4 * k4 + eb5 * k5 + eb6 * k6 + - eb7 * k7 + eb8 * k8 - end - - step_limiter!(u, integrator, p, t + dt) - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - @.. broadcast=false tmp=btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + - ebtilde1 * k1 + ebtilde4 * k4 + ebtilde5 * k5 + - ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 - else - @.. broadcast=false tmp=btilde1 * z₁ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ - end - - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.f(integrator.fsallast, u, p, t + dt) - else - @.. broadcast=false integrator.fsallast=z₈ / dt - end -end - -@muladd function perform_step!(integrator, cache::KenCarp47ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab - @unpack α31, α32, α41, α42, α43, α51, α52, α61, α62, α63, α71, α72, α73, α74, α75, α76 = cache.tab - @unpack btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76 = cache.tab - @unpack eb3, eb4, eb5, eb6, eb7 = cache.tab - @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - ##### Step 1 - - if integrator.f isa SplitFunction - # Explicit tableau is not FSAL - # Make this not compute on repeat - z₁ = dt .* f(uprev, p, t) - else - # FSAL Step 1 - z₁ = dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = z₁ - - tmp = uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - k1 = dt * integrator.fsalfirst - z₁ - tmp += ea21 * k1 - end - nlsolver.tmp = tmp - nlsolver.c = 2γ - - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ = z₂ - u = nlsolver.tmp + γ * z₂ - k2 = dt * f2(u, p, t + 2γdt) - integrator.stats.nf2 += 1 - tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - z₃ = α31 * z₁ + α32 * z₂ - tmp = uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - nlsolver.tmp = tmp - nlsolver.c = c3 - - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ = z₃ - u = nlsolver.tmp + γ * z₃ - k3 = dt * f2(u, p, t + c3 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 - else - z₄ = α41 * z₁ + α42 * z₂ + α43 * z₃ - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - nlsolver.tmp = tmp - nlsolver.c = c4 - - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ = z₁ - u = nlsolver.tmp + γ * z₄ - k4 = dt * f2(u, p, t + c4 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea52 * k2 + - ea53 * k3 + ea54 * k4 - else - z₅ = α51 * z₁ + α52 * z₂ - tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - nlsolver.tmp = tmp - nlsolver.c = c5 - - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ = z₃ - u = nlsolver.tmp + γ * z₅ - k5 = dt * f2(u, p, t + c5 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + - ea62 * k2 + ea63 * k3 + ea64 * k4 + ea65 * k5 - else - z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ - tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - nlsolver.tmp = tmp - nlsolver.c = c6 - - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - if integrator.f isa SplitFunction - z₇ = z₆ - u = nlsolver.tmp + γ * z₆ - k6 = dt * f2(u, p, t + c6 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + ea71 * k1 + ea72 * k2 + - ea73 * k3 + ea74 * k4 + ea75 * k5 + ea76 * k6 - else - z₇ = α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ + +α76 * z₆ - tmp = uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - end - nlsolver.z = z₇ - nlsolver.c = 1 - nlsolver.tmp = tmp - - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₇ - if integrator.f isa SplitFunction - k7 = dt * f2(u, p, t + dt) - u = uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + γ * z₇ + eb3 * k3 + - eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 - end - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + - ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + ebtilde6 * k6 + - ebtilde7 * k7 - else - tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ - end - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.k[1] = integrator.fsalfirst - integrator.fsallast = integrator.f(u, p, t + dt) - integrator.k[2] = integrator.fsallast - else - integrator.fsallast = z₇ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - end - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::KenCarp47Cache, repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver = cache - @unpack k1, k2, k3, k4, k5, k6, k7 = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a73, a74, a75, a76, c3, c4, c5, c6 = cache.tab - @unpack α31, α32, α41, α42, α43, α51, α52, α61, α62, α63, α71, α72, α73, α74, α75, α76 = cache.tab - @unpack btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76 = cache.tab - @unpack eb3, eb4, eb5, eb6, eb7 = cache.tab - @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - ##### Step 1 - - if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail - # Explicit tableau is not FSAL - # Make this not compute on repeat - f(z₁, integrator.uprev, p, integrator.t) - z₁ .*= dt - else - # FSAL Step 1 - @.. broadcast=false z₁=dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Allow other choices here - z₂ .= z₁ - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ - @.. broadcast=false tmp+=ea21 * k1 - end - - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ .= z₂ - @.. broadcast=false u=tmp + γ * z₂ - f2(k2, u, p, t + 2γdt) - k2 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - #Guess is from Hermite derivative on z₁ and z₂ - @.. broadcast=false z₃=a31 * z₁ + α32 * z₂ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ .= z₃ - @.. broadcast=false u=tmp + γ * z₃ - f2(k3, u, p, t + c3 * dt) - k3 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + - ea42 * k2 + ea43 * k3 - else - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ + α43 * z₃ - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ .= z₁ - @.. broadcast=false u=tmp + γ * z₄ - f2(k4, u, p, t + c4 * dt) - k4 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + - ea51 * k1 + ea52 * k2 + ea53 * k3 + ea54 * k4 - else - @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ .= z₃ - @.. broadcast=false u=tmp + γ * z₅ - f2(k5, u, p, t + c5 * dt) - k5 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + - a65 * z₅ + ea61 * k1 + ea62 * k2 + ea63 * k3 + ea64 * k4 + - ea65 * k5 - else - @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - if integrator.f isa SplitFunction - z₇ .= z₆ - @.. broadcast=false u=tmp + γ * z₆ - f2(k6, u, p, t + c6 * dt) - k6 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + - ea71 * k1 + ea72 * k2 + ea73 * k3 + ea74 * k4 + ea75 * k5 + - ea76 * k6 - else - @.. broadcast=false z₇=α71 * z₁ + α72 * z₂ + α73 * z₃ + α74 * z₄ + α75 * z₅ + - α76 * z₆ - @.. broadcast=false tmp=uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - end - nlsolver.z = z₇ - - nlsolver.c = 1 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₇ - if integrator.f isa SplitFunction - f2(k7, u, p, t + dt) - k7 .*= dt - integrator.stats.nf += 1 - @.. broadcast=false u=uprev + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + γ * z₇ + - eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 - end - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + ebtilde3 * k3 + - ebtilde4 * k4 + ebtilde5 * k5 + ebtilde6 * k6 + - ebtilde7 * k7 - else - @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ - end - - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.f(integrator.fsallast, u, p, t + dt) - else - @.. broadcast=false integrator.fsallast=z₇ / dt - end -end - -@muladd function perform_step!(integrator, cache::KenCarp58ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - nlsolver = cache.nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a83, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab - @unpack α31, α32, α41, α42, α51, α52, α61, α62, α63, α71, α72, α73, α81, α82, α83, α84, α85, α86, α87 = cache.tab - @unpack btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab - @unpack ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, ea85, ea86, ea87 = cache.tab - @unpack eb3, eb4, eb5, eb6, eb7, eb8 = cache.tab - @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - # calculate W - markfirststage!(nlsolver) - - ##### Step 1 - - if integrator.f isa SplitFunction - # Explicit tableau is not FSAL - # Make this not compute on repeat - z₁ = dt .* f(uprev, p, t) - else - # FSAL Step 1 - z₁ = dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Add extrapolation choice - - nlsolver.z = z₂ = z₁ - - tmp = uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - k1 = dt * integrator.fsalfirst - z₁ - tmp += ea21 * k1 - end - nlsolver.tmp = tmp - nlsolver.c = 2γ - - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ = z₂ - u = nlsolver.tmp + γ * z₂ - k2 = dt * f2(u, p, t + 2γdt) - integrator.stats.nf2 += 1 - tmp = uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - z₃ = α31 * z₁ + α32 * z₂ - tmp = uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - nlsolver.c = c3 - nlsolver.tmp = tmp - - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ = z₁ - u = nlsolver.tmp + γ * z₃ - k3 = dt * f2(u, p, t + c3 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + ea42 * k2 + ea43 * k3 - else - z₄ = α41 * z₁ + α42 * z₂ - tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - nlsolver.c = c4 - nlsolver.tmp = tmp - - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ = z₂ - u = nlsolver.tmp + γ * z₄ - k4 = dt * f2(u, p, t + c4 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + ea51 * k1 + ea52 * k2 + - ea53 * k3 + ea54 * k4 - else - z₅ = α51 * z₁ + α52 * z₂ - tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - nlsolver.c = c5 - nlsolver.tmp = tmp - - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ = z₃ - u = nlsolver.tmp + γ * z₅ - k5 = dt * f2(u, p, t + c5 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ + ea61 * k1 + - ea62 * k2 + ea63 * k3 + ea64 * k4 + ea65 * k5 - else - z₆ = α61 * z₁ + α62 * z₂ + α63 * z₃ - tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - nlsolver.c = c6 - nlsolver.tmp = tmp - - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - if integrator.f isa SplitFunction - z₇ = z₃ - u = nlsolver.tmp + γ * z₆ - k6 = dt * f2(u, p, t + c6 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ + - ea71 * k1 + ea72 * k2 + ea73 * k3 + ea74 * k4 + ea75 * k5 + ea76 * k6 - else - z₇ = α71 * z₁ + α72 * z₂ + α73 * z₃ - tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - end - nlsolver.z = z₇ - nlsolver.c = c7 - nlsolver.tmp = tmp - - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - if integrator.f isa SplitFunction - z₈ = z₇ - u = nlsolver.tmp + γ * z₇ - k7 = dt * f2(u, p, t + c7 * dt) - integrator.stats.nf2 += 1 - tmp = uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + ea81 * k1 + - ea82 * k2 + ea83 * k3 + ea84 * k4 + ea85 * k5 + ea86 * k6 + ea87 * k7 - else - z₈ = α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ + α86 * z₆ + α87 * z₇ - tmp = uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ - end - nlsolver.z = z₈ - nlsolver.c = 1 - nlsolver.tmp = tmp - - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₈ - if integrator.f isa SplitFunction - k8 = dt * f2(u, p, t + dt) - integrator.stats.nf2 += 1 - u = uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + γ * z₈ + - eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + eb7 * k7 + eb8 * k8 - end - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + - btilde8 * z₈ + ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + - ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 - else - tmp = btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + - btilde8 * z₈ - end - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.k[1] = integrator.fsalfirst - integrator.fsallast = integrator.f(u, p, t + dt) - integrator.k[2] = integrator.fsallast - else - integrator.fsallast = z₈ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - end - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::KenCarp58Cache, repeat_step = false) - @unpack t, dt, uprev, u, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver = cache - @unpack k1, k2, k3, k4, k5, k6, k7, k8 = cache - @unpack tmp = nlsolver - @unpack γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a83, a84, a85, a86, a87, c3, c4, c5, c6, c7 = cache.tab - @unpack α31, α32, α41, α42, α51, α52, α61, α62, α63, α71, α72, α73, α81, α82, α83, α84, α85, α86, α87 = cache.tab - @unpack btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab - @unpack ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, ea63, ea64, ea65 = cache.tab - @unpack ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, ea85, ea86, ea87 = cache.tab - @unpack eb3, eb4, eb5, eb6, eb7, eb8 = cache.tab - @unpack ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8 = cache.tab - alg = unwrap_alg(integrator, true) - - if integrator.f isa SplitFunction - f = integrator.f.f1 - f2 = integrator.f.f2 - else - f = integrator.f - end - - # precalculations - γdt = γ * dt - - markfirststage!(nlsolver) - - ##### Step 1 - - if integrator.f isa SplitFunction && !repeat_step && !integrator.last_stepfail - # Explicit tableau is not FSAL - # Make this not compute on repeat - f(z₁, integrator.uprev, p, integrator.t) - z₁ .*= dt - else - # FSAL Step 1 - @.. broadcast=false z₁=dt * integrator.fsalfirst - end - - ##### Step 2 - - # TODO: Allow other choices here - z₂ .= z₁ - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - - if integrator.f isa SplitFunction - # This assumes the implicit part is cheaper than the explicit part - @.. broadcast=false k1=dt * integrator.fsalfirst - z₁ - @.. broadcast=false tmp+=ea21 * k1 - end - - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - if integrator.f isa SplitFunction - z₃ .= z₂ - @.. broadcast=false u=tmp + γ * z₂ - f2(k2, u, p, t + 2γdt) - k2 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ + ea31 * k1 + ea32 * k2 - else - # Guess is from Hermite derivative on z₁ and z₂ - @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - end - nlsolver.z = z₃ - - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - if integrator.f isa SplitFunction - z₄ .= z₁ - @.. broadcast=false u=tmp + γ * z₃ - f2(k3, u, p, t + c3 * dt) - k3 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ + ea41 * k1 + - ea42 * k2 + ea43 * k3 - else - @.. broadcast=false z₄=α41 * z₁ + α42 * z₂ - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - end - nlsolver.z = z₄ - - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - if integrator.f isa SplitFunction - z₅ .= z₂ - @.. broadcast=false u=tmp + γ * z₄ - f2(k4, u, p, t + c4 * dt) - k4 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ + - ea51 * k1 + ea52 * k2 + ea53 * k3 + ea54 * k4 - else - @.. broadcast=false z₅=α51 * z₁ + α52 * z₂ - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - end - nlsolver.z = z₅ - - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - if integrator.f isa SplitFunction - z₆ .= z₃ - @.. broadcast=false u=tmp + γ * z₅ - f2(k5, u, p, t + c5 * dt) - k5 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + - a65 * z₅ + ea61 * k1 + ea62 * k2 + ea63 * k3 + ea64 * k4 + - ea65 * k5 - else - @.. broadcast=false z₆=α61 * z₁ + α62 * z₂ + α63 * z₃ - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - end - nlsolver.z = z₆ - - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - if integrator.f isa SplitFunction - z₇ .= z₃ - @.. broadcast=false u=tmp + γ * z₆ - f2(k6, u, p, t + c6 * dt) - k6 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + - a75 * z₅ + a76 * z₆ + ea71 * k1 + ea72 * k2 + ea73 * k3 + - ea74 * k4 + ea75 * k5 + ea76 * k6 - else - @.. broadcast=false z₇=α71 * z₁ + α72 * z₂ + α73 * z₃ - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + - a75 * z₅ + a76 * z₆ - end - nlsolver.z = z₇ - - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - if integrator.f isa SplitFunction - z₈ .= z₇ - @.. broadcast=false u=tmp + γ * z₇ - f2(k7, u, p, t + c7 * dt) - k7 .*= dt - integrator.stats.nf2 += 1 - @.. broadcast=false tmp=uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + - a87 * z₇ + ea81 * k1 + ea82 * k2 + ea83 * k3 + ea84 * k4 + - ea85 * k5 + ea86 * k6 + ea87 * k7 - else - @.. broadcast=false z₈=α81 * z₁ + α82 * z₂ + α83 * z₃ + α84 * z₄ + α85 * z₅ + - α86 * z₆ + α87 * z₇ - @.. broadcast=false tmp=uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ - end - nlsolver.z = z₈ - - nlsolver.c = 1 - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₈ - if integrator.f isa SplitFunction - f2(k8, u, p, t + dt) - k8 .*= dt - integrator.stats.nf += 1 - @.. broadcast=false u=uprev + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ + - γ * z₈ + eb3 * k3 + eb4 * k4 + eb5 * k5 + eb6 * k6 + - eb7 * k7 + eb8 * k8 - end - - ################################### Finalize - - if integrator.opts.adaptive - if integrator.f isa SplitFunction - @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + - ebtilde3 * k3 + ebtilde4 * k4 + ebtilde5 * k5 + - ebtilde6 * k6 + ebtilde7 * k7 + ebtilde8 * k8 - else - @.. broadcast=false tmp=btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ - end - - if isnewton(nlsolver) && alg.smooth_est # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - if integrator.f isa SplitFunction - integrator.f(integrator.fsallast, u, p, t + dt) - else - @.. broadcast=false integrator.fsallast=z₈ / dt - end -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl deleted file mode 100644 index eafca44bd1..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl +++ /dev/null @@ -1,998 +0,0 @@ -abstract type SDIRKMutableCache <: OrdinaryDiffEqMutableCache end - -@cache mutable struct ImplicitEulerCache{ - uType, rateType, uNoUnitsType, N, AV, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - uprev2::uType - fsalfirst::rateType - atmp::uNoUnitsType - nlsolver::N - algebraic_vars::AV - step_limiter!::StepLimiter -end - -function alg_cache(alg::ImplicitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - algebraic_vars = f.mass_matrix === I ? nothing : - [all(iszero, x) for x in eachcol(f.mass_matrix)] - - ImplicitEulerCache( - u, uprev, uprev2, fsalfirst, atmp, nlsolver, algebraic_vars, alg.step_limiter!) -end - -mutable struct ImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - -function alg_cache(alg::ImplicitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - ImplicitEulerConstantCache(nlsolver) -end - -mutable struct ImplicitMidpointConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - -function alg_cache(alg::ImplicitMidpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 2, 1 // 2 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - ImplicitMidpointConstantCache(nlsolver) -end - -@cache mutable struct ImplicitMidpointCache{uType, rateType, N, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - nlsolver::N - step_limiter!::StepLimiter -end - -function alg_cache(alg::ImplicitMidpoint, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 2, 1 // 2 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - ImplicitMidpointCache(u, uprev, fsalfirst, nlsolver, alg.step_limiter!) -end - -mutable struct TrapezoidConstantCache{uType, tType, N} <: OrdinaryDiffEqConstantCache - uprev3::uType - tprev2::tType - nlsolver::N -end - -function alg_cache(alg::Trapezoid, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 2, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - uprev3 = u - tprev2 = t - - TrapezoidConstantCache(uprev3, tprev2, nlsolver) -end - -@cache mutable struct TrapezoidCache{ - uType, rateType, uNoUnitsType, tType, N, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - uprev2::uType - fsalfirst::rateType - atmp::uNoUnitsType - uprev3::uType - tprev2::tType - nlsolver::N - step_limiter!::StepLimiter -end - -function alg_cache(alg::Trapezoid, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 2, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - uprev3 = zero(u) - tprev2 = t - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - TrapezoidCache( - u, uprev, uprev2, fsalfirst, atmp, uprev3, tprev2, nlsolver, alg.step_limiter!) -end - -mutable struct TRBDF2ConstantCache{Tab, N} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::TRBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = TRBDF2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.d, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - TRBDF2ConstantCache(nlsolver, tab) -end - -@cache mutable struct TRBDF2Cache{uType, rateType, uNoUnitsType, Tab, N, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - zprev::uType - zᵧ::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -function alg_cache(alg::TRBDF2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = TRBDF2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.d, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - zprev = zero(u) - zᵧ = zero(u) - - TRBDF2Cache(u, uprev, fsalfirst, zprev, zᵧ, atmp, nlsolver, tab, alg.step_limiter!) -end - -mutable struct SDIRK2ConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - -function alg_cache(alg::SDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - SDIRK2ConstantCache(nlsolver) -end - -@cache mutable struct SDIRK2Cache{uType, rateType, uNoUnitsType, N, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - atmp::uNoUnitsType - nlsolver::N - step_limiter!::StepLimiter -end - -function alg_cache(alg::SDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SDIRK2Cache(u, uprev, fsalfirst, z₁, z₂, atmp, nlsolver, alg.step_limiter!) -end - -struct SDIRK22ConstantCache{uType, tType, N, Tab} <: OrdinaryDiffEqConstantCache - uprev3::uType - tprev2::tType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SDIRK22, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{tTypeNoUnits}, ::Type{uBottomEltypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SDIRK22Tableau(constvalue(uBottomEltypeNoUnits)) - uprev3 = u - tprev2 = t - γ, c = 1, 1 - - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - - SDIRK22ConstantCache(uprev3, tprev2, nlsolver) -end - -@cache mutable struct SDIRK22Cache{ - uType, rateType, uNoUnitsType, tType, N, Tab, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - uprev2::uType - fsalfirst::rateType - atmp::uNoUnitsType - uprev3::uType - tprev2::tType - nlsolver::N - tab::Tab - step_limiter!::StepLimiter -end - -function alg_cache(alg::SDIRK22, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SDIRK22Tableau(constvalue(uBottomEltypeNoUnits)) - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - uprev3 = zero(u) - tprev2 = t - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SDIRK22Cache( - u, uprev, uprev2, fsalfirst, atmp, uprev3, tprev2, nlsolver, tab, alg.step_limiter!) # shouldn't this be SDIRK22Cache instead of SDIRK22? -end - -mutable struct SSPSDIRK2ConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - -function alg_cache(alg::SSPSDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 4, 1 // 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - SSPSDIRK2ConstantCache(nlsolver) -end - -@cache mutable struct SSPSDIRK2Cache{uType, rateType, N} <: SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - nlsolver::N -end - -function alg_cache(alg::SSPSDIRK2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1 // 4, 1 // 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SSPSDIRK2Cache(u, uprev, fsalfirst, z₁, z₂, nlsolver) -end - -mutable struct Cash4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::Cash4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Cash4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - Cash4ConstantCache(nlsolver, tab) -end - -@cache mutable struct Cash4Cache{uType, rateType, uNoUnitsType, N, Tab} <: SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::Cash4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = Cash4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - Cash4Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab) -end - -mutable struct SFSDIRK4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - SFSDIRK4ConstantCache(nlsolver, tab) -end - -@cache mutable struct SFSDIRK4Cache{uType, rateType, uNoUnitsType, N, Tab} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK4, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SFSDIRK4Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab) -end - -mutable struct SFSDIRK5ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - SFSDIRK5ConstantCache(nlsolver, tab) -end - -@cache mutable struct SFSDIRK5Cache{uType, rateType, uNoUnitsType, N, Tab} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK5, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK5Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SFSDIRK5Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, tab) -end - -mutable struct SFSDIRK6ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK6Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - SFSDIRK6ConstantCache(nlsolver, tab) -end - -@cache mutable struct SFSDIRK6Cache{uType, rateType, uNoUnitsType, N, Tab} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK6, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK6Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SFSDIRK6Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, tab) -end - -mutable struct SFSDIRK7ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK7, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK7Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - SFSDIRK7ConstantCache(nlsolver, tab) -end - -@cache mutable struct SFSDIRK7Cache{uType, rateType, uNoUnitsType, N, Tab} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK7, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK7Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SFSDIRK7Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, tab) -end - -mutable struct SFSDIRK8ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK8, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK8Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - SFSDIRK8ConstantCache(nlsolver, tab) -end - -@cache mutable struct SFSDIRK8Cache{uType, rateType, uNoUnitsType, N, Tab} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - z₈::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::SFSDIRK8, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = SFSDIRK8Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = zero(u) - z₈ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - SFSDIRK8Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver, tab) -end - -mutable struct Hairer4ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache( - alg::Union{Hairer4, Hairer42}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - if alg isa Hairer4 - tab = Hairer4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - else - tab = Hairer42Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - end - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - Hairer4ConstantCache(nlsolver, tab) -end - -@cache mutable struct Hairer4Cache{uType, rateType, uNoUnitsType, Tab, N} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache( - alg::Union{Hairer4, Hairer42}, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - if alg isa Hairer4 - tab = Hairer4Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - else # Hairer42 - tab = Hairer42Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - end - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - Hairer4Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, atmp, nlsolver, tab) -end - -@cache mutable struct ESDIRK54I8L2SACache{uType, rateType, uNoUnitsType, Tab, N} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - z₈::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK54I8L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK54I8L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = zero(u) - z₈ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - ESDIRK54I8L2SACache( - u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver, - tab) -end - -mutable struct ESDIRK54I8L2SAConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK54I8L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK54I8L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - ESDIRK54I8L2SAConstantCache(nlsolver, tab) -end - -@cache mutable struct ESDIRK436L2SA2Cache{uType, rateType, uNoUnitsType, Tab, N} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK436L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK436L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - ESDIRK436L2SA2Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver, - tab) -end - -mutable struct ESDIRK436L2SA2ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK436L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK436L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - ESDIRK436L2SA2ConstantCache(nlsolver, tab) -end - -@cache mutable struct ESDIRK437L2SACache{uType, rateType, uNoUnitsType, Tab, N} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK437L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK437L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - ESDIRK437L2SACache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, - tab) -end - -mutable struct ESDIRK437L2SAConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK437L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK437L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - ESDIRK437L2SAConstantCache(nlsolver, tab) -end - -@cache mutable struct ESDIRK547L2SA2Cache{uType, rateType, uNoUnitsType, Tab, N} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK547L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK547L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - ESDIRK547L2SA2Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver, - tab) -end - -mutable struct ESDIRK547L2SA2ConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK547L2SA2, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK547L2SA2Tableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - ESDIRK547L2SA2ConstantCache(nlsolver, tab) -end - -@cache mutable struct ESDIRK659L2SACache{uType, rateType, uNoUnitsType, Tab, N} <: - SDIRKMutableCache - u::uType - uprev::uType - fsalfirst::rateType - z₁::uType - z₂::uType - z₃::uType - z₄::uType - z₅::uType - z₆::uType - z₇::uType - z₈::uType - z₉::uType - atmp::uNoUnitsType - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK659L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, - dt, reltol, - p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK659L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - z₁ = zero(u) - z₂ = zero(u) - z₃ = zero(u) - z₄ = zero(u) - z₅ = zero(u) - z₆ = zero(u) - z₇ = zero(u) - z₈ = zero(u) - z₉ = nlsolver.z - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - ESDIRK659L2SACache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, z₉, atmp, - nlsolver, tab) -end - -mutable struct ESDIRK659L2SAConstantCache{N, Tab} <: OrdinaryDiffEqConstantCache - nlsolver::N - tab::Tab -end - -function alg_cache(alg::ESDIRK659L2SA, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, - uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{false}) where - {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - tab = ESDIRK659L2SATableau(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) - γ, c = tab.γ, tab.γ - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) - ESDIRK659L2SAConstantCache(nlsolver, tab) -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl deleted file mode 100644 index 84db426936..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl +++ /dev/null @@ -1,3154 +0,0 @@ -function initialize!(integrator, - cache::Union{ImplicitEulerConstantCache, - ImplicitMidpointConstantCache, - TrapezoidConstantCache, - TRBDF2ConstantCache, - SDIRK2ConstantCache, - SDIRK22ConstantCache, - SSPSDIRK2ConstantCache, - Cash4ConstantCache, - Hairer4ConstantCache, - ESDIRK54I8L2SAConstantCache, - ESDIRK436L2SA2ConstantCache, - ESDIRK437L2SAConstantCache, - ESDIRK547L2SA2ConstantCache, - ESDIRK659L2SAConstantCache, - SFSDIRK4ConstantCache, - SFSDIRK5ConstantCache, - SFSDIRK6ConstantCache, - SFSDIRK7ConstantCache, - SFSDIRK8ConstantCache}) - integrator.kshortsize = 2 - integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) - integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal - integrator.stats.nf += 1 - - # Avoid undefined entries if k is an array of arrays - integrator.fsallast = zero(integrator.fsalfirst) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast -end - -function initialize!(integrator, - cache::Union{ImplicitEulerCache, - ImplicitMidpointCache, - TrapezoidCache, - TRBDF2Cache, - SDIRK2Cache, - SDIRK22Cache, - SSPSDIRK2Cache, - Cash4Cache, - Hairer4Cache, - ESDIRK54I8L2SACache, - ESDIRK436L2SA2Cache, - ESDIRK437L2SACache, - ESDIRK547L2SA2Cache, - ESDIRK659L2SACache, - SFSDIRK4Cache, - SFSDIRK5Cache, - SFSDIRK6Cache, - SFSDIRK7Cache, - SFSDIRK8Cache}) - integrator.kshortsize = 2 - integrator.fsalfirst = cache.fsalfirst - integrator.fsallast = du_alias_or_new(cache.nlsolver, integrator.fsalfirst) - resize!(integrator.k, integrator.kshortsize) - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.f(integrator.fsalfirst, integrator.uprev, integrator.p, integrator.t) # For the interpolation, needs k at the updated point - integrator.stats.nf += 1 -end - -@muladd function perform_step!(integrator, cache::ImplicitEulerConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - nlsolver.z = dt * integrator.fsalfirst - else # :constant - nlsolver.z = zero(u) - end - - nlsolver.tmp = uprev - nlsolver.γ = 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = nlsolver.tmp + z - - if integrator.opts.adaptive && integrator.success_iter > 0 - # local truncation error (LTE) bound by dt^2/2*max|y''(t)| - # use 2nd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s - - tmp = r * - integrator.opts.internalnorm.((u - uprev) / dt1 - (uprev - uprev2) / dt2, t) - atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - integrator.EEst = 1 - end - - integrator.fsallast = f(u, p, t + dt) - - if integrator.opts.adaptive && integrator.differential_vars !== nothing - atmp = @. ifelse(!integrator.differential_vars, integrator.fsallast, false) ./ - integrator.opts.abstol - integrator.EEst += integrator.opts.internalnorm(atmp, t) - end - - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::ImplicitEulerCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack atmp, nlsolver, step_limiter! = cache - @unpack z, tmp = nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - @.. broadcast=false z=dt * integrator.fsalfirst - else # :constant - z .= zero(eltype(u)) - end - - nlsolver.tmp .= uprev - nlsolver.γ = 1 - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=uprev + z - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive && integrator.success_iter > 0 - # local truncation error (LTE) bound by dt^2/2*max|y''(t)| - # use 2nd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^2 # by mean value theorem 2nd DD equals y''(s)/2 for some s - - @.. broadcast=false tmp=r * integrator.opts.internalnorm( - (u - uprev) / dt1 - - (uprev - uprev2) / dt2, t) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - else - integrator.EEst = 1 - end - integrator.stats.nf += 1 - f(integrator.fsallast, u, p, t + dt) - - if integrator.opts.adaptive && integrator.differential_vars !== nothing - @.. broadcast=false atmp=ifelse(cache.algebraic_vars, integrator.fsallast, false) / - integrator.opts.abstol - integrator.EEst += integrator.opts.internalnorm(atmp, t) - end -end - -@muladd function perform_step!(integrator, cache::ImplicitMidpointConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - γ = 1 // 2 - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - nlsolver.z = dt * integrator.fsalfirst - else # :constant - nlsolver.z = zero(u) - end - - nlsolver.tmp = uprev - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = nlsolver.tmp + z - - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::ImplicitMidpointCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack nlsolver, step_limiter! = cache - @unpack z, tmp = nlsolver - mass_matrix = integrator.f.mass_matrix - alg = unwrap_alg(integrator, true) - γ = 1 // 2 - markfirststage!(nlsolver) - - # initial guess - if alg.extrapolant == :linear - @.. broadcast=false z=dt * integrator.fsalfirst - else # :constant - z .= zero(eltype(u)) - end - - nlsolver.tmp = uprev - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=nlsolver.tmp + z - - step_limiter!(u, integrator, p, t + dt) - - integrator.stats.nf += 1 - f(integrator.fsallast, u, p, t + dt) -end - -@muladd function perform_step!(integrator, cache::TrapezoidConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - # precalculations - γ = 1 // 2 - γdt = γ * dt - markfirststage!(nlsolver) - - # initial guess: constant extrapolation - nlsolver.z = uprev - - if f.mass_matrix === I - nlsolver.tmp = @.. broadcast=false uprev * inv(γdt)+integrator.fsalfirst - else - nlsolver.tmp = (f.mass_matrix * uprev) .* inv(γdt) .+ integrator.fsalfirst - end - nlsolver.α = 1 - nlsolver.γ = γ - nlsolver.method = COEFFICIENT_MULTISTEP - u = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - if integrator.opts.adaptive - if integrator.iter > 2 - # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| - # use 3rd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - uprev3 = cache.uprev3 - tprev2 = cache.tprev2 - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - dt3 = (t - tprev) * (t - tprev2) - dt4 = (tprev - tprev2) * (t - tprev2) - dt5 = t + dt - tprev2 - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s - - # tmp = r*abs(((u - uprev)/dt1 - (uprev - uprev2)/dt2) - ((uprev - uprev2)/dt3 - (uprev2 - uprev3)/dt4)/dt5) - DD31 = (u - uprev) / dt1 - (uprev - uprev2) / dt2 - DD30 = (uprev - uprev2) / dt3 - (uprev2 - uprev3) / dt4 - tmp = r * integrator.opts.internalnorm((DD31 - DD30) / dt5, t) - atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, - t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - if integrator.EEst <= 1 - cache.uprev3 = uprev2 - cache.tprev2 = tprev - end - elseif integrator.success_iter > 0 - integrator.EEst = 1 - cache.uprev3 = integrator.uprev2 - cache.tprev2 = integrator.tprev - else - integrator.EEst = 1 - end - end - - integrator.fsallast = f(u, p, t + dt) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::TrapezoidCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack atmp, nlsolver, step_limiter! = cache - @unpack z, tmp = nlsolver - alg = unwrap_alg(integrator, true) - mass_matrix = integrator.f.mass_matrix - - # precalculations - γ = 1 // 2 - γdt = γ * dt - markfirststage!(nlsolver) - - # initial guess: constant extrapolation - @.. broadcast=false z=uprev - invγdt = inv(γdt) - if mass_matrix === I - @.. broadcast=false tmp=uprev * invγdt + integrator.fsalfirst - else - mul!(u, mass_matrix, uprev) - @.. broadcast=false tmp=u * invγdt + integrator.fsalfirst - end - nlsolver.α = 1 - nlsolver.γ = γ - nlsolver.method = COEFFICIENT_MULTISTEP - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=z - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - if integrator.iter > 2 - # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| - # use 3rd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - uprev3 = cache.uprev3 - tprev2 = cache.tprev2 - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - dt3 = (t - tprev) * (t - tprev2) - dt4 = (tprev - tprev2) * (t - tprev2) - dt5 = t + dt - tprev2 - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s - - # @.. broadcast=false tmp = r*abs(((u - uprev)/dt1 - (uprev - uprev2)/dt2) - ((uprev - uprev2)/dt3 - (uprev2 - uprev3)/dt4)/dt5) - @.. broadcast=false tmp=r * integrator.opts.internalnorm( - (((u - uprev) / dt1 - - (uprev - uprev2) / dt2) #DD31 - - - ((uprev - uprev2) / dt3 - - (uprev2 - uprev3) / - dt4)) / - dt5, - t) - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - if integrator.EEst <= 1 - copyto!(cache.uprev3, uprev2) - cache.tprev2 = tprev - end - elseif integrator.success_iter > 0 - integrator.EEst = 1 - copyto!(cache.uprev3, integrator.uprev2) - cache.tprev2 = integrator.tprev - else - integrator.EEst = 1 - end - end - - integrator.stats.nf += 1 - f(integrator.fsallast, u, p, t + dt) -end - -@muladd function perform_step!(integrator, cache::TRBDF2ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, d, ω, btilde1, btilde2, btilde3, α1, α2 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # FSAL - zprev = dt * integrator.fsalfirst - - ##### Solve Trapezoid Step - - # TODO: Add extrapolation - zᵧ = zprev - nlsolver.z = zᵧ - nlsolver.c = γ - - nlsolver.tmp = uprev + d * zprev - zᵧ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve BDF2 Step - - ### Initial Guess From Shampine - z = α1 * zprev + α2 * zᵧ - nlsolver.z = z - nlsolver.c = 1 - - nlsolver.tmp = uprev + ω * zprev + ω * zᵧ - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + d * z - - ################################### Finalize - - if integrator.opts.adaptive - tmp = btilde1 * zprev + btilde2 * zᵧ + btilde3 * z - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::TRBDF2Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack zprev, zᵧ, atmp, nlsolver, step_limiter! = cache - @unpack z, tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - b = nlsolver.ztmp - @unpack γ, d, ω, btilde1, btilde2, btilde3, α1, α2 = cache.tab - alg = unwrap_alg(integrator, true) - - # FSAL - @.. broadcast=false zprev=dt * integrator.fsalfirst - markfirststage!(nlsolver) - - ##### Solve Trapezoid Step - - # TODO: Add extrapolation - @.. broadcast=false zᵧ=zprev - z .= zᵧ - @.. broadcast=false tmp=uprev + d * zprev - nlsolver.c = γ - zᵧ .= nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve BDF2 Step - - ### Initial Guess From Shampine - @.. broadcast=false z=α1 * zprev + α2 * zᵧ - @.. broadcast=false tmp=uprev + ω * zprev + ω * zᵧ - nlsolver.c = 1 - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + d * z - - step_limiter!(u, integrator, p, t + dt) - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * zprev + btilde2 * zᵧ + btilde3 * z - if alg.smooth_est && isnewton(nlsolver) # From Shampine - est = nlsolver.cache.dz - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z / dt -end - -@muladd function perform_step!(integrator, cache::TRBDF2Cache{<:Array}, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack zprev, zᵧ, atmp, nlsolver, step_limiter! = cache - @unpack z, tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - b = nlsolver.ztmp - @unpack γ, d, ω, btilde1, btilde2, btilde3, α1, α2 = cache.tab - alg = unwrap_alg(integrator, true) - - # FSAL - @inbounds @simd ivdep for i in eachindex(u) - zprev[i] = dt * integrator.fsalfirst[i] - end - markfirststage!(nlsolver) - - ##### Solve Trapezoid Step - - # TODO: Add extrapolation - copyto!(zᵧ, zprev) - copyto!(z, zᵧ) - @inbounds @simd ivdep for i in eachindex(u) - tmp[i] = uprev[i] + d * zprev[i] - end - nlsolver.c = γ - zᵧ .= nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve BDF2 Step - - ### Initial Guess From Shampine - @inbounds @simd ivdep for i in eachindex(u) - z[i] = α1 * zprev[i] + α2 * zᵧ[i] - end - @inbounds @simd ivdep for i in eachindex(u) - tmp[i] = uprev[i] + ω * zprev[i] + ω * zᵧ[i] - end - nlsolver.c = 1 - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @inbounds @simd ivdep for i in eachindex(u) - u[i] = tmp[i] + d * z[i] - end - - step_limiter!(u, integrator, p, t + dt) - - ################################### Finalize - - if integrator.opts.adaptive - @inbounds @simd ivdep for i in eachindex(u) - tmp[i] = btilde1 * zprev[i] + btilde2 * zᵧ[i] + btilde3 * z[i] - end - if alg.smooth_est && isnewton(nlsolver) # From Shampine - est = nlsolver.cache.dz - - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @inbounds @simd ivdep for i in eachindex(u) - integrator.fsallast[i] = z[i] / dt - end -end - -@muladd function perform_step!(integrator, cache::SDIRK2ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # initial guess - if integrator.success_iter > 0 && !integrator.reeval_fsal && - alg.extrapolant == :interpolant - current_extrapolant!(u, t + dt, integrator) - z₁ = u - uprev - elseif alg.extrapolant == :linear - z₁ = dt * integrator.fsalfirst - else - z₁ = zero(u) - end - - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ### Initial Guess Is α₁ = c₂/γ, c₂ = 0 => z₂ = α₁z₁ = 0 - z₂ = zero(u) - nlsolver.z = z₂ - nlsolver.tmp = uprev - z₁ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = uprev + z₁ / 2 + z₂ / 2 - - ################################### Finalize - - if integrator.opts.adaptive - tmp = z₁ / 2 - z₂ / 2 - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = f(u, p, t) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SDIRK2Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, atmp, nlsolver, step_limiter! = cache - @unpack tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # initial guess - if integrator.success_iter > 0 && !integrator.reeval_fsal && - alg.extrapolant == :interpolant - current_extrapolant!(u, t + dt, integrator) - @.. broadcast=false z₁=u - uprev - elseif alg.extrapolant == :linear - @.. broadcast=false z₁=dt * integrator.fsalfirst - else - z₁ .= zero(eltype(u)) - end - nlsolver.z = z₁ - - ##### Step 1 - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 2 - - ### Initial Guess Is α₁ = c₂/γ, c₂ = 0 => z₂ = α₁z₁ = 0 - z₂ .= zero(eltype(u)) - nlsolver.z = z₂ - isnewton(nlsolver) && set_new_W!(nlsolver, false) - @.. broadcast=false tmp=uprev - z₁ - nlsolver.tmp = tmp - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=uprev + z₁ / 2 + z₂ / 2 - - step_limiter!(u, integrator, p, t + dt) - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=z₁ / 2 - z₂ / 2 - if alg.smooth_est && isnewton(nlsolver) # From Shampine - est = nlsolver.cache.dz - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.stats.nf += 1 - f(integrator.fsallast, u, p, t) -end - -@muladd function perform_step!(integrator, cache::SDIRK22ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack a, α, β = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - # precalculations - γ = a * dt - γdt = γ * dt - markfirststage!(nlsolver) - - # initial guess - zprev = dt * integrator.fsalfirst - nlsolver.z = zprev - - # first stage - nlsolver.tmp = uprev + γdt * integrator.fsalfirst - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - uprev = α * nlsolver.tmp + β * z - - # final stage - γ = dt - γdt = γ * dt - markfirststage!(nlsolver) - nlsolver.tmp = uprev + γdt * integrator.fsalfirst - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - u = nlsolver.tmp - - if integrator.opts.adaptive - if integrator.iter > 2 - # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| - # use 3rd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - uprev3 = cache.uprev3 - tprev2 = cache.tprev2 - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - dt3 = (t - tprev) * (t - tprev2) - dt4 = (tprev - tprev2) * (t - tprev2) - dt5 = t + dt - tprev2 - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s - - DD31 = (u - uprev) / dt1 - (uprev - uprev2) / dt2 - DD30 = (uprev - uprev2) / dt3 - (uprev2 - uprev3) / dt4 - tmp = r * abs((DD31 - DD30) / dt5) - atmp = calculate_residuals(tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, - t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - if integrator.EEst <= 1 - cache.uprev3 = uprev2 - cache.tprev2 = tprev - end - elseif integrator.success_iter > 0 - integrator.EEst = 1 - cache.uprev3 = integrator.uprev2 - cache.tprev2 = integrator.tprev - else - integrator.EEst = 1 - end - end - - integrator.stats.nf += 2 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SDIRK22Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack atmp, nlsolver, step_limiter! = cache - @unpack z, tmp = nlsolver - @unpack a, α, β = cache.tab - alg = unwrap_alg(integrator, true) - mass_matrix = integrator.f.mass_matrix - - # precalculations - γ = a * dt - γdt = γ * dt - markfirststage!(nlsolver) - - # first stage - @.. broadcast=false z=dt * integrator.fsalfirst - @.. broadcast=false tmp=uprev + γdt * integrator.fsalfirst - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=α * tmp + β * z - - # final stage - γ = dt - γdt = γ * dt - markfirststage!(nlsolver) - @.. broadcast=false tmp=uprev + γdt * integrator.fsalfirst - z = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - @.. broadcast=false u=nlsolver.tmp - - step_limiter!(u, integrator, p, t + dt) - - if integrator.opts.adaptive - if integrator.iter > 2 - # local truncation error (LTE) bound by dt^3/12*max|y'''(t)| - # use 3rd divided differences (DD) a la SPICE and Shampine - - # TODO: check numerical stability - uprev2 = integrator.uprev2 - tprev = integrator.tprev - uprev3 = cache.uprev3 - tprev2 = cache.tprev2 - - dt1 = dt * (t + dt - tprev) - dt2 = (t - tprev) * (t + dt - tprev) - dt3 = (t - tprev) * (t - tprev2) - dt4 = (tprev - tprev2) * (t - tprev2) - dt5 = t + dt - tprev2 - c = 7 / 12 # default correction factor in SPICE (LTE overestimated by DD) - r = c * dt^3 / 2 # by mean value theorem 3rd DD equals y'''(s)/6 for some s - - @inbounds for i in eachindex(u) - DD31 = (u[i] - uprev[i]) / dt1 - (uprev[i] - uprev2[i]) / dt2 - DD30 = (uprev[i] - uprev2[i]) / dt3 - (uprev2[i] - uprev3[i]) / dt4 - tmp[i] = r * abs((DD31 - DD30) / dt5) - end - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - if integrator.EEst <= 1 - copyto!(cache.uprev3, uprev2) - cache.tprev2 = tprev - end - elseif integrator.success_iter > 0 - integrator.EEst = 1 - copyto!(cache.uprev3, integrator.uprev2) - cache.tprev2 = integrator.tprev - else - integrator.EEst = 1 - end - end - - integrator.stats.nf += 2 - f(integrator.fsallast, u, p, t + dt) -end - -@muladd function perform_step!(integrator, cache::SSPSDIRK2ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - γ = eltype(u)(1 // 4) - c2 = typeof(t)(3 // 4) - - markfirststage!(nlsolver) - - # initial guess - if integrator.success_iter > 0 && !integrator.reeval_fsal && - alg.extrapolant == :interpolant - current_extrapolant!(u, t + dt, integrator) - z₁ = u - uprev - elseif alg.extrapolant == :linear - z₁ = dt * integrator.fsalfirst - else - z₁ = zero(u) - end - nlsolver.z = z₁ - - ##### Step 1 - - tstep = t + dt - u = uprev + γ * z₁ - - nlsolver.c = 1 - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 2 - - ### Initial Guess Is α₁ = c₂/γ - z₂ = c2 / γ - nlsolver.z = z₂ - - nlsolver.tmp = uprev + z₁ / 2 - nlsolver.c = 1 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + z₂ / 2 - - ################################### Finalize - - integrator.fsallast = f(u, p, t) - integrator.stats.nf += 1 - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SSPSDIRK2Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, nlsolver = cache - @unpack tmp = nlsolver - alg = unwrap_alg(integrator, true) - - γ = eltype(u)(1 // 4) - c2 = typeof(t)(3 // 4) - markfirststage!(nlsolver) - - # initial guess - if integrator.success_iter > 0 && !integrator.reeval_fsal && - alg.extrapolant == :interpolant - current_extrapolant!(u, t + dt, integrator) - @.. broadcast=false z₁=u - uprev - elseif alg.extrapolant == :linear - @.. broadcast=false z₁=dt * integrator.fsalfirst - else - z₁ .= zero(eltype(u)) - end - nlsolver.z = z₁ - nlsolver.tmp = uprev - - ##### Step 1 - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 2 - - ### Initial Guess Is α₁ = c₂/γ - @.. broadcast=false z₂=c2 / γ - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + z₁ / 2 - nlsolver.tmp = tmp - isnewton(nlsolver) && set_new_W!(nlsolver, false) - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + z₂ / 2 - - ################################### Finalize - - integrator.stats.nf += 1 - f(integrator.fsallast, u, p, t) -end - -@muladd function perform_step!(integrator, cache::Cash4ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab - @unpack b1hat1, b2hat1, b3hat1, b4hat1, b1hat2, b2hat2, b3hat2, b4hat2 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ = zero(u) - nlsolver.z = z₁ - - nlsolver.c = γ - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ = zero(u) - nlsolver.z = z₂ - - nlsolver.tmp = uprev + a21 * z₁ - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - z₃ = z₁ - nlsolver.z = z₃ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - z₄ = z₃ - nlsolver.z = z₄ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use yhat2 for prediction - z₅ = b1hat2 * z₁ + b2hat2 * z₂ + b3hat2 * z₃ + b4hat2 * z₄ - nlsolver.z = z₅ - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = 1 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₅ - - ################################### Finalize - - if integrator.opts.adaptive - if alg.embedding == 3 - btilde1 = b1hat2 - a51 - btilde2 = b2hat2 - a52 - btilde3 = b3hat2 - a53 - btilde4 = b4hat2 - a54 - btilde5 = -γ - else - btilde1 = b1hat1 - a51 - btilde2 = b2hat1 - a52 - btilde3 = b3hat1 - a53 - btilde4 = b4hat1 - a54 - btilde5 = -γ - end - - tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₅ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::Cash4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, atmp, nlsolver = cache - @unpack tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab - @unpack b1hat1, b2hat1, b3hat1, b4hat1, b1hat2, b2hat2, b3hat2, b4hat2 = cache.tab - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ .= zero(eltype(z₁)) - nlsolver.z = z₁ - nlsolver.c = γ - nlsolver.tmp = uprev - - # initial step of NLNewton iteration - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(z₂)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + a21 * z₁ - nlsolver.tmp = tmp - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - @.. broadcast=false z₃=z₁ - nlsolver.z = z₃ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=z₃ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - @.. broadcast=false z₅=b1hat2 * z₁ + b2hat2 * z₂ + b3hat2 * z₃ + b4hat2 * z₄ - nlsolver.z = z₅ - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = 1 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₅ - - ################################### Finalize - - if integrator.opts.adaptive - if alg.embedding == 3 - btilde1 = b1hat2 - a51 - btilde2 = b2hat2 - a52 - btilde3 = b3hat2 - a53 - btilde4 = b4hat2 - a54 - btilde5 = -γ - else - btilde1 = b1hat1 - a51 - btilde2 = b2hat1 - a52 - btilde3 = b3hat1 - a53 - btilde4 = b4hat1 - a54 - btilde5 = -γ - end - - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ - if alg.smooth_est && isnewton(nlsolver) # From Shampine - est = nlsolver.cache.dz - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₅ / dt -end - -@muladd function perform_step!(integrator, cache::SFSDIRK4ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ = zero(u) - nlsolver.z = z₁ - - nlsolver.c = γ - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ = zero(u) - nlsolver.z = z₂ - - nlsolver.tmp = uprev + a21 * z₁ - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - z₃ = z₁ - nlsolver.z = z₃ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - z₄ = z₃ - nlsolver.z = z₄ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Final Step - - u = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - - integrator.fsallast = z₄ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SFSDIRK4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, nlsolver = cache - @unpack tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ .= zero(eltype(z₁)) - nlsolver.z = z₁ - nlsolver.c = γ - nlsolver.tmp = uprev - - # initial step of NLNewton iteration - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(z₂)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + a21 * z₁ - nlsolver.tmp = tmp - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - @.. broadcast=false z₃=z₁ - nlsolver.z = z₃ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=z₃ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - - ################################### Finalize - @.. broadcast=false integrator.fsallast=z₄ / dt -end - -@muladd function perform_step!(integrator, cache::SFSDIRK5ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, c2, c3, c4, c5 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ = zero(u) - nlsolver.z = z₁ - - nlsolver.c = γ - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ = zero(u) - nlsolver.z = z₂ - - nlsolver.tmp = uprev + a21 * z₁ - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - z₃ = z₁ - nlsolver.z = z₃ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - z₄ = z₃ - nlsolver.z = z₄ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - z₅ = z₄ - nlsolver.z = z₅ - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Final Step - - u = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - - integrator.fsallast = z₅ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SFSDIRK5Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, nlsolver = cache - @unpack tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, c2, c3, c4, c5 = cache.tab - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ .= zero(eltype(z₁)) - nlsolver.z = z₁ - nlsolver.c = γ - nlsolver.tmp = uprev - - # initial step of NLNewton iteration - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(z₂)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + a21 * z₁ - nlsolver.tmp = tmp - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - @.. broadcast=false z₃=z₁ - nlsolver.z = z₃ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=z₃ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - @.. broadcast=false z₅=z₄ - nlsolver.z = z₅ - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - ################################### Finalize - @.. broadcast=false u=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - - @.. broadcast=false integrator.fsallast=z₅ / dt -end - -@muladd function perform_step!(integrator, cache::SFSDIRK6ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, c2, c3, c4, c5, c6 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ = zero(u) - nlsolver.z = z₁ - - nlsolver.c = γ - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ = zero(u) - nlsolver.z = z₂ - - nlsolver.tmp = uprev + a21 * z₁ - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - z₃ = z₁ - nlsolver.z = z₃ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - z₄ = z₃ - nlsolver.z = z₄ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - z₅ = z₄ - nlsolver.z = z₅ - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - z₆ = z₅ - nlsolver.z = z₆ - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Final Step - - u = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - - integrator.fsallast = z₆ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SFSDIRK6Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, nlsolver = cache - @unpack tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, c2, c3, c4, c5, c6 = cache.tab - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ .= zero(eltype(z₁)) - nlsolver.z = z₁ - nlsolver.c = γ - nlsolver.tmp = uprev - - # initial step of NLNewton iteration - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(z₂)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + a21 * z₁ - nlsolver.tmp = tmp - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - @.. broadcast=false z₃=z₁ - nlsolver.z = z₃ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=z₃ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - @.. broadcast=false z₅=z₄ - nlsolver.z = z₅ - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - # Use constant z prediction - @.. broadcast=false z₆=z₅ - nlsolver.z = z₆ - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################### Finalize - @.. broadcast=false u=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ - - @.. broadcast=false integrator.fsallast=z₆ / dt -end - -@muladd function perform_step!(integrator, cache::SFSDIRK7ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, c2, c3, c4, c5, c6, c7 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ = zero(u) - nlsolver.z = z₁ - - nlsolver.c = γ - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ = zero(u) - nlsolver.z = z₂ - - nlsolver.tmp = uprev + a21 * z₁ - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - z₃ = z₁ - nlsolver.z = z₃ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - z₄ = z₃ - nlsolver.z = z₄ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - z₅ = z₄ - nlsolver.z = z₅ - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - # Use constant z prediction - z₆ = z₅ - nlsolver.z = z₆ - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - # Use constant z prediction - z₇ = z₆ - nlsolver.z = z₇ - - nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Final Step - - u = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + a87 * z₇ - - integrator.fsallast = z₇ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SFSDIRK7Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, nlsolver = cache - @unpack tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, c2, c3, c4, c5, c6, c7 = cache.tab - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ .= zero(eltype(z₁)) - nlsolver.z = z₁ - nlsolver.c = γ - nlsolver.tmp = uprev - - # initial step of NLNewton iteration - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(z₂)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + a21 * z₁ - nlsolver.tmp = tmp - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - @.. broadcast=false z₃=z₁ - nlsolver.z = z₃ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=z₃ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - @.. broadcast=false z₅=z₄ - nlsolver.z = z₅ - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - # Use constant z prediction - @.. broadcast=false z₆=z₅ - nlsolver.z = z₆ - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - # Use constant z prediction - @.. broadcast=false z₇=z₆ - nlsolver.z = z₇ - - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################### Finalize - @.. broadcast=false u=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + - a86 * z₆ + a87 * z₇ - - @.. broadcast=false integrator.fsallast=z₇ / dt -end - -@muladd function perform_step!(integrator, cache::SFSDIRK8ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, a91, a92, a93, a94, a95, a96, a97, a98, c2, c3, c4, c5, c6, c7, c8 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ = zero(u) - nlsolver.z = z₁ - - nlsolver.c = γ - nlsolver.tmp = uprev - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ = zero(u) - nlsolver.z = z₂ - - nlsolver.tmp = uprev + a21 * z₁ - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - z₃ = z₁ - nlsolver.z = z₃ - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - z₄ = z₃ - nlsolver.z = z₄ - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - z₅ = z₄ - nlsolver.z = z₅ - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - # Use constant z prediction - z₆ = z₅ - nlsolver.z = z₆ - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - # Use constant z prediction - z₇ = z₆ - nlsolver.z = z₇ - - nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - # Use constant z prediction - z₈ = z₇ - nlsolver.z = z₈ - - nlsolver.tmp = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + - a87 * z₇ - nlsolver.c = c8 - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Final Step - - u = uprev + a91 * z₁ + a92 * z₂ + a93 * z₃ + a94 * z₄ + a95 * z₅ + a96 * z₆ + a97 * z₇ + - a98 * z₈ - - integrator.fsallast = z₈ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::SFSDIRK8Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, nlsolver = cache - @unpack tmp = nlsolver - W = isnewton(nlsolver) ? get_W(nlsolver) : nothing - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, a91, a92, a93, a94, a95, a96, a97, a98, c2, c3, c4, c5, c6, c7, c8 = cache.tab - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - ##### Step 1 - - # TODO: Add extrapolation for guess - z₁ .= zero(eltype(z₁)) - nlsolver.z = z₁ - nlsolver.c = γ - nlsolver.tmp = uprev - - # initial step of NLNewton iteration - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(z₂)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + a21 * z₁ - nlsolver.tmp = tmp - isnewton(nlsolver) && set_new_W!(nlsolver, false) - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - # Guess starts from z₁ - @.. broadcast=false z₃=z₁ - nlsolver.z = z₃ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=z₃ - nlsolver.z = z₄ - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use constant z prediction - @.. broadcast=false z₅=z₄ - nlsolver.z = z₅ - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - # Use constant z prediction - @.. broadcast=false z₆=z₅ - nlsolver.z = z₆ - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - # Use constant z prediction - @.. broadcast=false z₇=z₆ - nlsolver.z = z₇ - - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - # Use constant z prediction - @.. broadcast=false z₈=z₇ - nlsolver.z = z₈ - - @.. broadcast=false tmp=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + - a86 * z₆ + a87 * z₇ - nlsolver.c = c8 - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################### Finalize - @.. broadcast=false u=uprev + a91 * z₁ + a92 * z₂ + a93 * z₃ + a94 * z₄ + a95 * z₅ + - a96 * z₆ + a97 * z₇ + a98 * z₈ - - @.. broadcast=false integrator.fsallast=z₈ / dt -end - -@muladd function perform_step!(integrator, cache::Hairer4ConstantCache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab - @unpack α21, α31, α32, α41, α43 = cache.tab - @unpack bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # TODO: Add extrapolation for guess - z₁ = zero(u) - nlsolver.z, nlsolver.tmp = z₁, uprev - nlsolver.c = γ - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - z₂ = α21 * z₁ - nlsolver.z = z₂ - nlsolver.tmp = uprev + a21 * z₁ - nlsolver.c = c2 - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - z₃ = α31 * z₁ + α32 * z₂ - nlsolver.z = z₃ - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - z₄ = α41 * z₁ + α43 * z₃ - nlsolver.z = z₄ - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use yhat2 for prediction - z₅ = bhat1 * z₁ + bhat2 * z₂ + bhat3 * z₃ + bhat4 * z₄ - nlsolver.z = z₅ - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = 1 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₅ - - ################################### Finalize - - if integrator.opts.adaptive - tmp = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ - if isnewton(nlsolver) && alg.smooth_est # From Shampine - integrator.stats.nsolve += 1 - est = _reshape(get_W(nlsolver) \ _vec(tmp), axes(tmp)) - else - est = tmp - end - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₅ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u -end - -@muladd function perform_step!(integrator, cache::Hairer4Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, atmp, nlsolver = cache - @unpack tmp = nlsolver - @unpack γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4 = cache.tab - @unpack α21, α31, α32, α41, α43 = cache.tab - @unpack bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, btilde4, btilde5 = cache.tab - alg = unwrap_alg(integrator, true) - markfirststage!(nlsolver) - - # initial guess - if integrator.success_iter > 0 && !integrator.reeval_fsal && - alg.extrapolant == :interpolant - current_extrapolant!(u, t + dt, integrator) - @.. broadcast=false z₁=u - uprev - elseif alg.extrapolant == :linear - @.. broadcast=false z₁=dt * integrator.fsalfirst - else - z₁ .= zero(eltype(z₁)) - end - nlsolver.z = z₁ - nlsolver.tmp = uprev - - ##### Step 1 - - nlsolver.c = γ - z₁ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ##### Step 2 - - @.. broadcast=false z₂=α21 * z₁ - nlsolver.z = z₂ - @.. broadcast=false tmp=uprev + a21 * z₁ - nlsolver.tmp = tmp - nlsolver.c = c2 - isnewton(nlsolver) && set_new_W!(nlsolver, false) - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - @.. broadcast=false z₃=α31 * z₁ + α32 * z₂ - nlsolver.z = z₃ - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - @.. broadcast=false z₄=α41 * z₁ + α43 * z₃ - nlsolver.z = z₄ - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - # Use yhat prediction - @.. broadcast=false z₅=bhat1 * z₁ + bhat2 * z₂ + bhat3 * z₃ + bhat4 * z₄ - nlsolver.z = z₅ - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = 1 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₅ - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ - if alg.smooth_est && isnewton(nlsolver) # From Shampine - est = nlsolver.cache.dz - linres = dolinsolve(integrator, nlsolver.cache.linsolve; b = _vec(tmp), - linu = _vec(est)) - - integrator.stats.nsolve += 1 - else - est = tmp - end - calculate_residuals!(atmp, est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₅ / dt -end - -@muladd function perform_step!(integrator, cache::ESDIRK54I8L2SAConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - a81, a82, a83, a84, a85, a86, a87, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # TODO: Add extrapolation for guess - - ##### Step 1 - - z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = zero(z₁) - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - nlsolver.z = z₃ = zero(z₂) - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = zero(z₃) - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = z₅ = zero(z₄) - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = z₆ = zero(z₅) - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - nlsolver.z = z₇ = zero(z₆) - - nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - nlsolver.z = z₈ = zero(z₇) - - nlsolver.tmp = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + - a87 * z₇ - nlsolver.c = 1 - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₈ - - ################################### Finalize - - if integrator.opts.adaptive - est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₈ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK54I8L2SACache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, atmp, nlsolver = cache - @unpack tmp = nlsolver - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - a81, a82, a83, a84, a85, a86, a87, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - ##### Step 1 - - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(u)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - nlsolver.z = fill!(z₃, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - nlsolver.z = fill!(z₄, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = fill!(z₅, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = fill!(z₆, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - nlsolver.z = fill!(z₇, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - nlsolver.z = fill!(z₈, zero(eltype(u))) - - @.. broadcast=false nlsolver.tmp=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + - a85 * z₅ + a86 * z₆ + a87 * z₇ - nlsolver.c = oneunit(nlsolver.c) - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₈ - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₈ / dt - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK436L2SA2ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - c3, c4, c5, c6, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # TODO: Add extrapolation for guess - - ##### Step 1 - - z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = zero(z₁) - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - nlsolver.z = z₃ = zero(z₂) - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = zero(z₃) - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = z₅ = zero(z₄) - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = z₆ = zero(z₅) - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₆ - - ################################### Finalize - - if integrator.opts.adaptive - est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₆ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK436L2SA2Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, atmp, nlsolver = cache - @unpack tmp = nlsolver - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - c3, c4, c5, c6, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - ##### Step 1 - - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(u)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - nlsolver.z = fill!(z₃, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - nlsolver.z = fill!(z₄, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = fill!(z₅, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = fill!(z₆, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₆ - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ + btilde6 * z₆ - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₆ / dt - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK437L2SAConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # TODO: Add extrapolation for guess - - ##### Step 1 - - z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = zero(z₁) - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - nlsolver.z = z₃ = zero(z₂) - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = zero(z₃) - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = z₅ = zero(z₄) - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = z₆ = zero(z₅) - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - nlsolver.z = z₇ = zero(z₆) - - nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₇ - - ################################### Finalize - - if integrator.opts.adaptive - est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₇ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK437L2SACache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver = cache - @unpack tmp = nlsolver - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - ##### Step 1 - - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(u)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - nlsolver.z = fill!(z₃, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - nlsolver.z = fill!(z₄, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = fill!(z₅, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = fill!(z₆, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = fill!(z₇, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₇ - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₇ / dt - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK547L2SA2ConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # TODO: Add extrapolation for guess - - ##### Step 1 - - z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = zero(z₁) - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - nlsolver.z = z₃ = zero(z₂) - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = zero(z₃) - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = z₅ = zero(z₄) - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = z₆ = zero(z₅) - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - nlsolver.z = z₇ = zero(z₆) - - nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₇ - - ################################### Finalize - - if integrator.opts.adaptive - est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₇ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK547L2SA2Cache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, atmp, nlsolver = cache - @unpack tmp = nlsolver - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - ##### Step 1 - - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(u)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - nlsolver.z = fill!(z₃, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - nlsolver.z = fill!(z₄, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = fill!(z₅, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = fill!(z₆, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - nlsolver.z = fill!(z₇, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₇ - - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ + btilde6 * z₆ + btilde7 * z₇ - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₇ / dt - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK659L2SAConstantCache, - repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - a81, a82, a83, a84, a85, a86, a87, - a94, a95, a96, a97, a98, - c3, c4, c5, c6, c7, c8, c9, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9 = cache.tab - nlsolver = cache.nlsolver - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - # TODO: Add extrapolation for guess - - ##### Step 1 - - z₁ = dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation choice - nlsolver.z = z₂ = zero(z₁) - - nlsolver.tmp = uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 3 - - nlsolver.z = z₃ = zero(z₂) - - nlsolver.tmp = uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - nlsolver.z = z₄ = zero(z₃) - - nlsolver.tmp = uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = z₅ = zero(z₄) - - nlsolver.tmp = uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = z₆ = zero(z₅) - - nlsolver.tmp = uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - nlsolver.z = z₇ = zero(z₆) - - nlsolver.tmp = uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - nlsolver.z = z₈ = zero(z₇) - - nlsolver.tmp = uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + a86 * z₆ + - a87 * z₇ - nlsolver.c = c8 - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 9 - nlsolver.z = z₉ = zero(z₈) - - nlsolver.tmp = uprev + a94 * z₄ + a95 * z₅ + a96 * z₆ + a97 * z₇ + a98 * z₈ - nlsolver.c = c9 - z₉ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - u = nlsolver.tmp + γ * z₉ - - ################################### Finalize - - if integrator.opts.adaptive - est = btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + btilde9 * z₉ - atmp = calculate_residuals(est, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - integrator.fsallast = z₉ ./ dt - integrator.k[1] = integrator.fsalfirst - integrator.k[2] = integrator.fsallast - integrator.u = u - return -end - -@muladd function perform_step!(integrator, cache::ESDIRK659L2SACache, repeat_step = false) - @unpack t, dt, uprev, u, f, p = integrator - @unpack z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, z₉, atmp, nlsolver = cache - @unpack tmp = nlsolver - @unpack γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - a81, a82, a83, a84, a85, a86, a87, - a94, a95, a96, a97, a98, - c3, c4, c5, c6, c7, c8, c9, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, btilde8, btilde9 = cache.tab - alg = unwrap_alg(integrator, true) - - # precalculations - γdt = γ * dt - markfirststage!(nlsolver) - - ##### Step 1 - - @.. broadcast=false z₁=dt * integrator.fsalfirst - - ##### Step 2 - - # TODO: Add extrapolation for guess - z₂ .= zero(eltype(u)) - nlsolver.z = z₂ - - @.. broadcast=false tmp=uprev + γ * z₁ - nlsolver.c = 2γ - z₂ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - isnewton(nlsolver) && set_new_W!(nlsolver, false) - - ################################## Solve Step 3 - - nlsolver.z = fill!(z₃, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a31 * z₁ + a32 * z₂ - nlsolver.c = c3 - z₃ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 4 - - # Use constant z prediction - nlsolver.z = fill!(z₄, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a41 * z₁ + a42 * z₂ + a43 * z₃ - nlsolver.c = c4 - z₄ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 5 - - nlsolver.z = fill!(z₅, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a51 * z₁ + a52 * z₂ + a53 * z₃ + a54 * z₄ - nlsolver.c = c5 - z₅ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 6 - - nlsolver.z = fill!(z₆, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a61 * z₁ + a62 * z₂ + a63 * z₃ + a64 * z₄ + a65 * z₅ - nlsolver.c = c6 - z₆ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 7 - - nlsolver.z = fill!(z₇, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a71 * z₁ + a72 * z₂ + a73 * z₃ + a74 * z₄ + a75 * z₅ + - a76 * z₆ - nlsolver.c = c7 - z₇ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 8 - - nlsolver.z = fill!(z₈, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a81 * z₁ + a82 * z₂ + a83 * z₃ + a84 * z₄ + a85 * z₅ + - a86 * z₆ + a87 * z₇ - nlsolver.c = c8 - z₈ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - ################################## Solve Step 9 - - nlsolver.z = fill!(z₉, zero(eltype(u))) - - @.. broadcast=false tmp=uprev + a94 * z₄ + a95 * z₅ + a96 * z₆ + a97 * z₇ + a98 * z₈ - nlsolver.c = c9 - z₉ = nlsolve!(nlsolver, integrator, cache, repeat_step) - nlsolvefail(nlsolver) && return - - @.. broadcast=false u=tmp + γ * z₉ - ################################### Finalize - - if integrator.opts.adaptive - @.. broadcast=false tmp=btilde1 * z₁ + btilde2 * z₂ + btilde3 * z₃ + btilde4 * z₄ + - btilde5 * z₅ + - btilde6 * z₆ + btilde7 * z₇ + btilde8 * z₈ + btilde9 * z₉ - calculate_residuals!(atmp, tmp, uprev, u, integrator.opts.abstol, - integrator.opts.reltol, integrator.opts.internalnorm, t) - integrator.EEst = integrator.opts.internalnorm(atmp, t) - end - - @.. broadcast=false integrator.fsallast=z₉ / dt - return -end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl deleted file mode 100644 index f008557fda..0000000000 --- a/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl +++ /dev/null @@ -1,2776 +0,0 @@ -struct TRBDF2Tableau{T, T2} - γ::T2 - d::T - ω::T - btilde1::T - btilde2::T - btilde3::T - α1::T - α2::T -end - -#= -Tableau: - -c = [0; γ; 1] -A = [0 0 0 - d d 0 - ω ω d] -b = [ω; ω; d] -bhat = [(1-ω)/3; (3ω+1)/3; d/3] - -where γ=2-√2, d=γ/2, and ω=(√2)/4. Hence - -btilde = bhat-b = [(1-4ω)/3; 1/3; -2d/3] = [(1-√2)/3; 1/3; (√2-2)/3] - -Let uᵧ and u be approximations to u(t+γ*dt) and u(t+dt). Then initial guesses of -approximations zᵧ and z to dt*f(t+γ*dt,uᵧ) and dt*f(t+dt,u) according to Shampine: - -zᵧ = zprev - -z = (1.5+√2)*zprev + (2.5+2√2)*zᵧ - (6+4.5√2)*(uᵧ-uprev) = (by def. of uᵧ) - = (1.5+√2)*zprev + (2.5+2√2)*zᵧ - (6+4.5√2)*(d*zᵧ + d*zprev) = - = (-√2)/2*zprev + (1+(√2)/2)*zᵧ -=# -function TRBDF2Tableau(T, T2) - γ = convert(T2, 2 - sqrt(2)) - d = convert(T, 1 - sqrt(2) / 2) - ω = convert(T, sqrt(2) / 4) - btilde1 = convert(T, (1 - sqrt(2)) / 3) - btilde2 = convert(T, 1 // 3) - btilde3 = convert(T, (sqrt(2) - 2) / 3) - α1 = convert(T, -sqrt(2) / 2) - α2 = convert(T, 1 + sqrt(2) / 2) - TRBDF2Tableau(γ, d, ω, btilde1, btilde2, btilde3, α1, α2) -end - -struct ESDIRK4Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - btilde1::T - btilde2::T - btilde3::T - btilde4::T - c3::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 -end - -#= -Derivative of Hermite Polynomial -k[1] + Θ*(-4*dt*k[1] - 2*dt*k[2] - 6*y₀ + Θ*(3*dt*k[1] + 3*dt*k[2] + 6*y₀ - 6*y₁) + 6*y₁)/dt - -Extrapolation for ESDIRK interior step 3 -dt = c2 since interval is [c1,c2] and c1 = 0 -θ = c3/c2 the extrapolation point -z = dt*k - -z₁ + Θ*(-4dt*z₁ - 2dt*z₂ - 6y₀ + Θ*(3dt*z₁ + 3z₂ + 6y₀ - 6y₁ ) + 6y₁)/dt - -Test Expression on TRBDF2: -c2 = 2 - sqrt(2) -c3 = 1 -θ = c3/c2; dt = c2 - -Coefficient on z₁: -(1 + (-4θ + 3θ^2))*z₁ -1 + (-4θ + 3θ^2) - (1.5 + sqrt(2)) # 1.5 + sqrt(2) given by Shampine - -Coefficient on z₂: -(-2θ + 3θ^2)*z₂ -(-2θ + 3θ^2) - (2.5 + 2sqrt(2)) # 2.5 + 2sqrt(2) given by Shampine - -Coefficient on y₁-y₀: -θ*(θ*6(y₀-y₁)+6(y₁-y₀))/dt -θ*(-6θ(y₁-y₀)+6(y₁-y₀))/dt -(y₁-y₀)6θ*(1-θ)/dt - -(6θ*(1-θ)/dt)*(y₁-y₀) - -6θ*(1-θ)/dt - (- (6 + 4.5sqrt(2))) # - (6 + 4.5sqrt(2)) given by Shampine - -# Write only in terms of z primitives -y₀ = uprev -y₁ = uprev + γ*z₁ + γ*z₂ -y₁-y₀ = γ*z₁ + γ*z₂ - -# Full Expression -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/dt)*γ)*z₁ + ((-2θ + 3θ^2) + (6θ*(1-θ)/dt)*γ)*z₂ -=# - -#= -# Kvaerno3 -# Predict z4 from yhat - -yhat = uprev + a31*z1 + a32*z2 + γ*z3 -z₄ = yhat - uprev = a31*z1 + a32*z2 + γ*z3 - -# Note Hermite is too small of an interval for this one!!! -=# - -function Kvaerno3Tableau(T, T2) - γ = convert(T2, 0.4358665215) - a31 = convert(T, 0.490563388419108) - a32 = convert(T, 0.073570090080892) - a41 = convert(T, 0.308809969973036) - a42 = convert(T, 1.490563388254106) - a43 = -convert(T, 1.235239879727145) - # bhat1 = convert(T,0.490563388419108) - # bhat2 = convert(T,0.073570090080892) - # bhat3 = convert(T,0.4358665215) - # bhat4 = convert(T,0.0) - btilde1 = convert(T, 0.181753418446072) # bhat1-a41 - btilde2 = convert(T, -1.416993298173214) # bhat2-a42 - btilde3 = convert(T, 1.671106401227145) # bhat3-a43 - btilde4 = convert(T, -γ) # bhat4-γ - c3 = convert(T2, 1) - c2 = 2γ - θ = c3 / c2 - α31 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) - α32 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) - α41 = convert(T2, 0.0) - α42 = convert(T2, 0.0) - ESDIRK4Tableau(γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, - α32, α41, α42) -end - -struct KenCarp3Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - btilde1::T - btilde2::T - btilde3::T - btilde4::T - c3::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 - ea21::T - ea31::T - ea32::T - ea41::T - ea42::T - ea43::T - eb1::T - eb2::T - eb3::T - eb4::T - ebtilde1::T - ebtilde2::T - ebtilde3::T - ebtilde4::T -end - -#= -# KenCarp3 -# Predict z4 from Hermite z2 and z1 -# Not z3 because c3 < c2 ! - -θ = c3/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) -θ = c4/c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) -=# -function KenCarp3Tableau(T::Type{<:CompiledFloats}, T2::Type{<:CompiledFloats}) - γ = convert(T2, 0.435866521508459) - a31 = convert(T, 0.2576482460664272) - a32 = -convert(T, 0.09351476757488625) - a41 = convert(T, 0.18764102434672383) - a42 = -convert(T, 0.595297473576955) - a43 = convert(T, 0.9717899277217721) - # bhat1 = convert(T,2756255671327//12835298489170) - # bhat2 = -convert(T,10771552573575//22201958757719) - # bhat3 = convert(T,9247589265047//10645013368117) - # bhat4 = convert(T,2193209047091//5459859503100) - btilde1 = convert(T, 0.027099261876665316) # bhat1-a41 - btilde2 = convert(T, 0.11013520969201586) # bhat2-a42 - btilde3 = convert(T, -0.10306492520138458) # bhat3-a43 - btilde4 = convert(T, -0.0341695463672966) # bhat4-γ - c3 = convert(T2, 0.6) - c2 = 2γ - θ = c3 / c2 - α31 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) - α32 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) - θ = 1 / c2 - α41 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) - α42 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) - - ea21 = convert(T, 0.871733043016918) - ea31 = convert(T, 0.5275890119763004) - ea32 = convert(T, 0.0724109880236996) - ea41 = convert(T, 0.3990960076760701) - ea42 = -convert(T, 0.4375576546135194) - ea43 = convert(T, 1.0384616469374492) - eb1 = convert(T, 0.18764102434672383) - eb2 = convert(T, -0.595297473576955) - eb3 = convert(T, 0.9717899277217721) - eb4 = convert(T, 0.435866521508459) - ebtilde1 = convert(T, 0.027099261876665316) - ebtilde2 = convert(T, 0.11013520969201586) - ebtilde3 = -convert(T, 0.10306492520138458) - ebtilde4 = -convert(T, 0.0341695463672966) - KenCarp3Tableau( - γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, - α32, α41, α42, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4, - ebtilde1, ebtilde2, ebtilde3, ebtilde4) -end - -function KenCarp3Tableau(T, T2) - γ = convert(T2, 1767732205903 // 4055673282236) - a31 = convert(T, 2746238789719 // 10658868560708) - a32 = -convert(T, 640167445237 // 6845629431997) - a41 = convert(T, 1471266399579 // 7840856788654) - a42 = -convert(T, 4482444167858 // 7529755066697) - a43 = convert(T, 11266239266428 // 11593286722821) - # bhat1 = convert(T,2756255671327//12835298489170) - # bhat2 = -convert(T,10771552573575//22201958757719) - # bhat3 = convert(T,9247589265047//10645013368117) - # bhat4 = convert(T,2193209047091//5459859503100) - btilde1 = convert(T, - BigInt(681815649026867975666107) // - BigInt(25159934323302256049469295)) # bhat1-a41 - btilde2 = convert(T, - BigInt(18411887981491912264464127) // - BigInt(167175311446532472108584143)) # bhat2-a42 - btilde3 = convert(T, - BigInt(-12719313754959329011138489) // - BigInt(123410692144842870217698057)) # bhat3-a43 - btilde4 = convert(T, - BigInt(-47289384293135913063989) // BigInt(1383962894467812063558225)) # bhat4-γ - c3 = convert(T2, 3 // 5) - c2 = 2γ - θ = c3 / c2 - α31 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) - α32 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) - θ = 1 / c2 - α41 = ((1 + (-4θ + 3θ^2)) + (6θ * (1 - θ) / c2) * γ) - α42 = ((-2θ + 3θ^2) + (6θ * (1 - θ) / c2) * γ) - - # Explicit Tableau - ea21 = convert(T, 1767732205903 // 2027836641118) - ea31 = convert(T, 5535828885825 // 10492691773637) - ea32 = convert(T, 788022342437 // 10882634858940) - ea41 = convert(T, 6485989280629 // 16251701735622) - ea42 = -convert(T, 4246266847089 // 9704473918619) - ea43 = convert(T, 10755448449292 // 10357097424841) - eb1 = convert(T, 1471266399579 // 7840856788654) - eb2 = convert(T, -4482444167858 // 7529755066697) - eb3 = convert(T, 11266239266428 // 11593286722821) - eb4 = convert(T, 1767732205903 // 4055673282236) - ebtilde1 = convert(T, - BigInt(681815649026867975666107) // - BigInt(25159934323302256049469295)) - ebtilde2 = convert(T, - BigInt(18411887981491912264464127) // - BigInt(167175311446532472108584143)) - ebtilde3 = -convert(T, - BigInt(12719313754959329011138489) // - BigInt(123410692144842870217698057)) - ebtilde4 = -convert(T, - BigInt(47289384293135913063989) // - BigInt(1383962894467812063558225)) - KenCarp3Tableau( - γ, a31, a32, a41, a42, a43, btilde1, btilde2, btilde3, btilde4, c3, α31, - α32, α41, α42, ea21, ea31, ea32, ea41, ea42, ea43, eb1, eb2, eb3, eb4, - ebtilde1, ebtilde2, ebtilde3, ebtilde4) -end - -# Flip them all! - -# ebtilde1 = big(1471266399579)//7840856788654 - big(2756255671327)//12835298489170 -# ebtilde2 = -big(4482444167858)//7529755066697 + big(10771552573575)//22201958757719 -# ebtilde3 = big(11266239266428)//11593286722821 - big(9247589265047)//10645013368117 -# ebtilde4 = big(1767732205903)//4055673282236 - big(2193209047091)//5459859503100 - -struct Cash4Tableau{T, T2} - γ::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - b1hat1::T - b2hat1::T - b3hat1::T - b4hat1::T - b1hat2::T - b2hat2::T - b3hat2::T - b4hat2::T - c2::T2 - c3::T2 - c4::T2 -end - -#= -Extrapolation for Cash interior step 3 -dt = c1-c2 since interval is [c2,c1] and c1 = 0 -c2 < c1, so z₂ is the left -θ = (c3-c1)/dt the extrapolation point -z = dt*k - -z₂ + Θ*(-4dt*z₂ - 2dt*z₁ - 6y₀ + Θ*(3dt*z₂ + 3z₁ + 6y₀ - 6y₁ ) + 6y₁)/dt - -Coefficient on z₁: -(-2θ + 3θ^2) - -Coefficient on z₂: -(1 + (-4θ + 3θ^2)) - -Coefficient on y₁-y₀: -(6θ*(1-θ)/dt) - -# Write only in terms of z primitives -y₁ = uprev + a21*z₁ + γ*z₂ -y₀ = uprev + γ*z₁ -y₁-y₀ = (a21-γ)*z₁ + γ*z₂ - -θ = 1.1 -Full z₁ coefficient: (-2θ + 3θ^2) + (6θ*(1-θ)/dt)*(a21-γ) -Full z₂ coefficient: (1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/dt)*γ - -f(θ)= (-2θ + 3θ^2) + (6θ*(1-θ)/dt)*(a21-γ) -g(θ) = (1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/dt)*γ -t = linspace(0,1.5,100) -y = f.(t) -z = g.(t) -plot(t,y) -plot!(t,z) - -The extrapolation is really bad that far -Hairer's extrapolation is no better. -Using constant extrapolations -=# - -function Cash4Tableau(T, T2) - γ = convert(T2, 0.435866521508) - a21 = convert(T, -1.13586652150) - a31 = convert(T, 1.08543330679) - a32 = -convert(T, 0.721299828287) - a41 = convert(T, 0.416349501547) - a42 = convert(T, 0.190984004184) - a43 = convert(T, -0.118643265417) - a51 = convert(T, 0.896869652944) - a52 = convert(T, 0.0182725272734) - a53 = -convert(T, 0.0845900310706) - a54 = -convert(T, 0.266418670647) - b1hat1 = convert(T, 1.05646216107052) - b2hat1 = -convert(T, 0.0564621610705236) - b3hat1 = convert(T, 0) - b4hat1 = convert(T, 0) - b1hat2 = convert(T, 0.776691932910) - b2hat2 = convert(T, 0.0297472791484) - b3hat2 = -convert(T, 0.0267440239074) - b4hat2 = convert(T, 0.220304811849) - c2 = -convert(T2, 0.7) - c3 = convert(T2, 0.8) - c4 = convert(T2, 0.924556761814) - Cash4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - b1hat1, b2hat1, b3hat1, b4hat1, b1hat2, b2hat2, b3hat2, b4hat2, c2, c3, c4) -end - -struct SFSDIRK4Tableau{T, T2} - γ::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - c2::T2 - c3::T2 - c4::T2 -end - -function SFSDIRK4Tableau(T, T2) - γ = convert(T2, 0.097961082941) - a21 = convert(T, 0.262318069183) - a31 = convert(T, 0.230169419019) - a32 = convert(T, 0.294466719347) - a41 = convert(T, 0.210562684389) - a42 = convert(T, 0.269382888280) - a43 = convert(T, 0.307008634881) - a51 = convert(T, 0.222119403264) - a52 = convert(T, 0.282060762166) - a53 = convert(T, 0.236881213175) - a54 = convert(T, 0.258938621395) - c2 = convert(T2, 0.360279152124) - c3 = convert(T2, 0.622597221298) - c4 = convert(T2, 0.884915290491) - SFSDIRK4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, c2, c3, c4) -end - -struct SFSDIRK5Tableau{T, T2} - γ::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - c2::T2 - c3::T2 - c4::T2 - c5::T2 -end - -function SFSDIRK5Tableau(T, T2) - γ = convert(T2, 0.078752939968) - a21 = convert(T, 0.222465723027) - a31 = convert(T, 0.203192361700) - a32 = convert(T, 0.230847263068) - a41 = convert(T, 0.188022704389) - a42 = convert(T, 0.191735630027) - a43 = convert(T, 0.209922288451) - a51 = convert(T, 0.188025114093) - a52 = convert(T, 0.191739898281) - a53 = convert(T, 0.209907601860) - a54 = convert(T, 0.252726086329) - a61 = convert(T, 0.192143833571) - a62 = convert(T, 0.200935182974) - a63 = convert(T, 0.205799262036) - a64 = convert(T, 0.200553844640) - a65 = convert(T, 0.200567876778) - c2 = convert(T2, 0.301218662995) - c3 = convert(T2, 0.512792564736) - c4 = convert(T2, 0.668433562835) - c5 = convert(T2, 0.921151640531) - SFSDIRK5Tableau( - γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, c2, c3, c4, c5) -end - -struct SFSDIRK6Tableau{T, T2} - γ::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 -end - -function SFSDIRK6Tableau(T, T2) - γ = convert(T2, 0.067410767219) - a21 = convert(T, 0.194216850802) - a31 = convert(T, 0.194216850802) - a32 = convert(T, 0.199861501713) - a41 = convert(T, 0.162188551749) - a42 = convert(T, 0.166902343330) - a43 = convert(T, 0.145120313717) - a51 = convert(T, 0.165176818500) - a52 = convert(T, 0.169977460026) - a53 = convert(T, 0.150227711763) - a54 = convert(T, 0.181214258555) - a61 = convert(T, 0.165176818500) - a62 = convert(T, 0.169977460026) - a63 = convert(T, 0.150227711763) - a64 = convert(T, 0.181214258555) - a65 = convert(T, 0.199861501713) - a71 = convert(T, 0.168954170460) - a72 = convert(T, 0.173864595628) - a73 = convert(T, 0.156683775305) - a74 = convert(T, 0.157643002581) - a75 = convert(T, 0.173864725004) - a76 = convert(T, 0.168989731022) - c2 = convert(T2, 0.261627618021) - c3 = convert(T2, 0.461489119734) - c4 = convert(T2, 0.541621976015) - c5 = convert(T2, 0.734007016063) - c6 = convert(T2, 0.933868517776) - SFSDIRK6Tableau( - γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, a71, a72, a73, a74, a75, a76, c2, c3, c4, c5, c6) -end - -struct SFSDIRK7Tableau{T, T2} - γ::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - a81::T - a82::T - a83::T - a84::T - a85::T - a86::T - a87::T - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 -end - -function SFSDIRK7Tableau(T, T2) - γ = convert(T2, 0.056879041592) - a21 = convert(T, 0.172205581756) - a31 = convert(T, 0.135485903539) - a32 = convert(T, 0.135485903539) - a41 = convert(T, 0.133962606568) - a42 = convert(T, 0.133962606568) - a43 = convert(T, 0.170269437596) - a51 = convert(T, 0.133962606568) - a52 = convert(T, 0.133962606568) - a53 = convert(T, 0.170269437596) - a54 = convert(T, 0.172205581756) - a61 = convert(T, 0.138004377067) - a62 = convert(T, 0.133084723451) - a63 = convert(T, 0.152274237527) - a64 = convert(T, 0.154005757170) - a65 = convert(T, 0.154005757170) - a71 = convert(T, 0.139433665640) - a72 = convert(T, 0.134719607258) - a73 = convert(T, 0.145910607076) - a74 = convert(T, 0.147569765489) - a75 = convert(T, 0.147569765489) - a76 = convert(T, 0.165009008641) - a81 = convert(T, 0.138370770799) - a82 = convert(T, 0.134572540279) - a83 = convert(T, 0.150642940425) - a84 = convert(T, 0.152355910489) - a85 = convert(T, 0.152355910489) - a86 = convert(T, 0.132951737506) - a87 = convert(T, 0.138750190012) - c2 = convert(T2, 0.229084623348) - c3 = convert(T2, 0.32785084867) - c4 = convert(T2, 0.495073692324) - c5 = convert(T2, 0.66727927408) - c6 = convert(T2, 0.788253893977) - c7 = convert(T2, 0.937091461185) - SFSDIRK7Tableau( - γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, - c2, c3, c4, c5, c6, c7) -end - -struct SFSDIRK8Tableau{T, T2} - γ::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - a81::T - a82::T - a83::T - a84::T - a85::T - a86::T - a87::T - a91::T - a92::T - a93::T - a94::T - a95::T - a96::T - a97::T - a98::T - c2::T2 - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - c8::T2 -end - -function SFSDIRK8Tableau(T, T2) - γ = convert(T2, 0.050353353407) - a21 = convert(T, 0.147724666662) - a31 = convert(T, 0.114455029802) - a32 = convert(T, 0.114455029802) - a41 = convert(T, 0.114147680771) - a42 = convert(T, 0.114147680771) - a43 = convert(T, 0.147327977820) - a51 = convert(T, 0.114163314686) - a52 = convert(T, 0.114163314686) - a53 = convert(T, 0.147259379853) - a54 = convert(T, 0.147655883990) - a61 = convert(T, 0.114163314686) - a62 = convert(T, 0.114163314686) - a63 = convert(T, 0.147259379853) - a64 = convert(T, 0.147655883990) - a65 = convert(T, 0.147724666662) - a71 = convert(T, 0.118472990244) - a72 = convert(T, 0.118472990244) - a73 = convert(T, 0.128349529304) - a74 = convert(T, 0.128695117609) - a75 = convert(T, 0.128755067770) - a76 = convert(T, 0.128755067770) - a81 = convert(T, 0.118472990244) - a82 = convert(T, 0.118472990244) - a83 = convert(T, 0.128349529304) - a84 = convert(T, 0.128695117609) - a85 = convert(T, 0.128755067770) - a86 = convert(T, 0.128755067770) - a87 = convert(T, 0.147724666662) - a91 = convert(T, 0.117592883046) - a92 = convert(T, 0.117592883046) - a93 = convert(T, 0.132211234288) - a94 = convert(T, 0.132567220450) - a95 = convert(T, 0.132628974356) - a96 = convert(T, 0.132293123539) - a97 = convert(T, 0.117556840638) - a98 = convert(T, 0.117556840638) - c2 = convert(T2, 0.198078020069) - c3 = convert(T2, 0.279263413011) - c4 = convert(T2, 0.425976692769) - c5 = convert(T2, 0.573595246622) - c6 = convert(T2, 0.721319913284) - c7 = convert(T2, 0.801854116348) - c8 = convert(T2, 0.94957878301) - SFSDIRK8Tableau( - γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, a71, a72, a73, a74, a75, a76, a81, a82, a83, a84, a85, a86, a87, - a91, a92, a93, a94, a95, a96, a97, a98, c2, c3, c4, c5, c6, c7, c8) -end - -struct Hairer4Tableau{T, T2} - γ::T2 - a21::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - bhat1::T - bhat2::T - bhat3::T - bhat4::T - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - c2::T2 - c3::T2 - c4::T2 - r11::T - r12::T - r13::T - r14::T - r21::T - r22::T - r23::T - r24::T - r31::T - r32::T - r33::T - r34::T - r41::T - r42::T - r43::T - r44::T - r51::T - r52::T - r53::T - r54::T - α21::T2 - α31::T2 - α32::T2 - α41::T2 - α43::T2 -end - -function Hairer4Tableau(T, T2) - γ = convert(T2, 1 // 4) - c2 = convert(T2, 3 // 4) - c3 = convert(T2, 11 // 20) - c4 = convert(T2, 1 // 2) - - #= - α21 = convert(T,2) - α31 = convert(T,42//25) - α32 = -convert(T,4//25) - α41 = convert(T,89//68) - α42 = -convert(T,25//136) - α43 = convert(T,15//136) - α51 = -convert(T,37//12) - α52 = -convert(T,103//24) - α53 = convert(T,275//8) - α54 = -convert(T,85//3) - - alpha = -inv(A)*γ - - α = [-1 0 0 0 0 - α21 -1 0 0 0 - α31 α32 -1 0 0 - α41 α42 α43 -1 0 - α51 α52 α53 α54 -1] - A α = -γ - A = -γ*inv(α) - - Now zⱼ = fⱼ + ∑α_ⱼᵢ zᵢ - =# - - a11 = convert(T, 1 // 4) - a21 = convert(T, 1 // 2) - a22 = convert(T, 1 // 4) - a31 = convert(T, 17 // 50) - a32 = convert(T, -1 // 25) - a33 = convert(T, 1 // 4) - a41 = convert(T, 371 // 1360) - a42 = convert(T, -137 // 2720) - a43 = convert(T, 15 // 544) - a44 = convert(T, 1 // 4) - a51 = convert(T, 25 // 24) - a52 = convert(T, -49 // 48) - a53 = convert(T, 125 // 16) - a54 = convert(T, -85 // 12) - - #= - e1 = -convert(T,23//6) - e2 = -convert(T,17//12) - e3 = convert(T,125//4) - e4 = -convert(T,85//3) - E = [e1 e2 e3 e4 0] - - bhat = [59//48,-17//96,225//32,-85//12,0] - - α = [-1 0 0 0 0 - α21 -1 0 0 0 - α31 α32 -1 0 0 - α41 α42 α43 -1 0 - e1 e2 e3 e4 -1] - - A = [γ 0 0 0 0 - a21 γ 0 0 0 - a31 a32 γ 0 0 - a41 a42 a43 γ 0 - a51 a52 a53 a54 γ] - - E = bhat'*inv(A) - bhat = E*A - =# - - bhat1 = convert(T, 59 // 48) - bhat2 = convert(T, -17 // 96) - bhat3 = convert(T, 225 // 32) - bhat4 = convert(T, -85 // 12) - - btilde1 = convert(T, 3 // 16) # bhat1-a51 - btilde2 = convert(T, 27 // 32) # bhat2-a52 - btilde3 = convert(T, -25 // 32) # bhat3-a53 - btilde4 = convert(T, 0) # bhat4-a54 - btilde5 = -γ - - #= - d11 = convert(T,61//27) - d12 = convert(T,-185//54) - d13 = convert(T,2525//18) - d14 = convert(T,-3740//27) - d15 = convert(T,-44//9) - d21 = convert(T,2315//81) - d22 = convert(T,1049//162) - d23 = convert(T,-27725//54) - d24 = convert(T,40460//81) - d25 = convert(T,557//27) - d31 = convert(T,-6178//81) - d32 = convert(T,-1607//81) - d33 = convert(T,20075//27) - d34 = convert(T,-56440//81) - d35 = convert(T,-718//27) - d41 = convert(T,3680//81) - d42 = convert(T,1360//81) - d43 = convert(T,-10000//27) - d44 = convert(T,27200//81) - d45 = convert(T,320//27) - - D = [d11 d12 d13 d14 d15 - d21 d22 d23 d24 d25 - d31 d32 d33 d34 d35 - d41 d42 d43 d44 d45] - R = (D*A)' - =# - - r11 = convert(T, 11 // 3) - r12 = convert(T, -463 // 72) - r13 = convert(T, 217 // 36) - r14 = convert(T, -20 // 9) - r21 = convert(T, 11 // 2) - r22 = convert(T, -385 // 16) - r23 = convert(T, 661 // 24) - r24 = convert(T, -10 // 1) - r31 = convert(T, -125 // 18) - r32 = convert(T, 20125 // 432) - r33 = convert(T, -8875 // 216) - r34 = convert(T, 250 // 27) - r41 = convert(T, 0) - r42 = convert(T, -85 // 4) - r43 = convert(T, 85 // 6) - r44 = convert(T, 0 // 1) - r51 = convert(T, -11 // 9) - r52 = convert(T, 557 // 108) - r53 = convert(T, -359 // 54) - r54 = convert(T, 80 // 27) - - # c2/γ - α21 = convert(T2, 3) - #= - # Prediction alphas from Hairer - # Predict z3 from z1 and z2 - A = [c1 c2 - γ*c1 a21*c1+γ*c2] - b = [c3,a31*c1+a32*c2+γ*c3] - A\b - =# - α31 = convert(T2, 88 // 100) - α32 = convert(T2, 44 // 100) - #= - # Predict z4 from z1 and z3 - A = [c1 c3 - γ*c1 a31*c1+a32*c2+γ*c3] - b = [c4,a41*c1+a42*c2+a43*c3+γ*c4] - A\b - =# - α41 = convert(T2, 3 // 17) - α43 = convert(T2, 155 // 187) - - Hairer4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, - btilde4, btilde5, c2, c3, c4, r11, r12, r13, r14, - r21, r22, r23, r24, r31, r32, r33, r34, r41, r42, r43, r44, r51, - r52, r53, r54, α21, α31, α32, α41, α43) -end - -function Hairer42Tableau(T, T2) - γ = convert(T, 4 // 15) - c2 = convert(T2, 23 // 30) - c3 = convert(T2, 17 // 30) - c4 = convert(T2, 2881 // 28965) + γ - #= - α21 = convert(T,15//8) - α31 = convert(T,1577061//922880) - α32 = -convert(T,23427//115360) - α41 = convert(T,647163682356923881//2414496535205978880) - α42 = -convert(T,593512117011179//3245291041943520) - α43 = convert(T,559907973726451//1886325418129671) - α51 = convert(T,724545451//796538880) - α52 = -convert(T,830832077//267298560) - α53 = convert(T,30957577//2509272) - α54 = -convert(T,69863904375173//6212571137048) - - α = [-1 0 0 0 0 - α21 -1 0 0 0 - α31 α32 -1 0 0 - α41 α42 α43 -1 0 - α51 α52 α53 α54 -1] - A = -γ*inv(α) - =# - a21 = convert(T, 1 // 2) - a31 = convert(T, 51069 // 144200) - a32 = convert(T, -7809 // 144200) - a41 = convert(T, 12047244770625658 // 141474406359725325) - a42 = convert(T, -3057890203562191 // 47158135453241775) - a43 = convert(T, 2239631894905804 // 28294881271945065) - a51 = convert(T, 181513 // 86430) - a52 = convert(T, -89074 // 116015) - a53 = convert(T, 83636 // 34851) - a54 = convert(T, -69863904375173 // 23297141763930) - - #= - - A = [γ 0 0 0 0 - a21 γ 0 0 0 - a31 a32 γ 0 0 - a41 a42 a43 γ 0 - a51 a52 a53 a54 γ] - - A = convert(Array{Rational{BigInt}},A) - - e1 = convert(T,7752107607//11393456128) - e2 = -convert(T,17881415427//11470078208) - e3 = convert(T,2433277665//179459416) - e4 = -convert(T,96203066666797//6212571137048) - E = [e1 e2 e3 e4 0] - - bhat = E*A - =# - - bhat1 = convert(T, 33665407 // 11668050) - bhat2 = convert(T, -2284766 // 15662025) - bhat3 = convert(T, 11244716 // 4704885) - bhat4 = convert(T, -96203066666797 // 23297141763930) - - btilde1 = convert(T, 4580576 // 5834025) # bhat1-a51 - btilde2 = convert(T, 9740224 // 15662025) # bhat2-a52 - btilde3 = convert(T, -46144 // 4704885) # bhat3-a53 - btilde4 = convert(T, -13169581145812 // 11648570881965) # bhat4-a54 - btilde5 = -γ - - #= - d11 = convert(T,24.74416644927758) - d12 = -convert(T,4.325375951824688) - d13 = convert(T,41.39683763286316) - d14 = convert(T,-61.04144619901784) - d15 = convert(T,-3.391332232917013) - d21 = convert(T,-51.98245719616925) - d22 = convert(T,10.52501981094525) - d23 = convert(T,-154.2067922191855) - d24 = convert(T,214.3082125319825) - d25 = convert(T,14.71166018088679) - d31 = convert(T,33.14347947522142) - d32 = convert(T,-19.72986789558523) - d33 = convert(T,230.4878502285804) - d34 = convert(T,-287.6629744338197) - d35 = convert(T,-18.99932366302254) - d41 = convert(T,-5.905188728329743) - d42 = convert(T,13.53022403646467) - d43 = convert(T,-117.6778956422581) - d44 = convert(T,134.3962081008550) - d45 = convert(T,8.678995715052762) - =# - - r11 = convert(T, 6.776439256624082) - r12 = convert(T, -14.066831911883533) - r13 = convert(T, 16.204808856162565) - r14 = convert(T, -6.8143005003361985) - r21 = convert(T, 3.166691382949011) - r22 = convert(T, -14.034196189427504) - r23 = convert(T, 15.497198116229603) - r24 = convert(T, -5.3974733381957005) - r31 = convert(T, -1.9310469085972866) - r32 = convert(T, 11.146663701107887) - r33 = convert(T, -6.9009212321038405) - r34 = convert(T, 0.085120800673252) - r41 = convert(T, -6.107728468864632) - r42 = convert(T, 13.031255018633459) - r43 = convert(T, -19.734599430149146) - r44 = convert(T, 9.812254180511282) - r51 = convert(T, -0.9043552621112034) - r52 = convert(T, 3.9231093815698106) - r53 = convert(T, -5.066486310139344) - r54 = convert(T, 2.3143988573474035) - - # c2/γ - α21 = convert(T, 23 // 8) - α31 = convert(T, 0.9838473040915402) - α32 = convert(T, 0.3969226768377252) - α41 = convert(T, 0.6563374010466914) - α43 = convert(T, 0.3372498196189311) - - Hairer4Tableau(γ, a21, a31, a32, a41, a42, a43, a51, a52, a53, a54, - bhat1, bhat2, bhat3, bhat4, btilde1, btilde2, btilde3, btilde4, btilde5, - c2, c3, c4, r11, r12, r13, r14, - r21, r22, r23, r24, r31, r32, r33, r34, r41, r42, r43, r44, r51, - r52, r53, r54, α21, α31, α32, α41, α43) -end - -struct Kvaerno4Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - c3::T2 - c4::T2 - α21::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 -end - -#= -# Kvaerno4 -# Predict z3 from Hermite z2 and z1 - -c2 = 2γ -θ = c3/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z4 from Hermite z2 and z1 - -θ = c4/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) -=# - -function Kvaerno4Tableau(T, T2) - γ = convert(T2, 0.4358665215) - a31 = convert(T, 0.140737774731968) - a32 = convert(T, -0.108365551378832) - a41 = convert(T, 0.102399400616089) - a42 = convert(T, -0.376878452267324) - a43 = convert(T, 0.838612530151233) - a51 = convert(T, 0.157024897860995) - a52 = convert(T, 0.117330441357768) - a53 = convert(T, 0.61667803039168) - a54 = convert(T, -0.326899891110444) - btilde1 = convert(T, -0.054625497244906) # a41 - a51 - btilde2 = convert(T, -0.494208893625092) # a42 - a52 - btilde3 = convert(T, 0.221934499759553) # a43 - a53 - btilde4 = convert(T, 0.762766412610444) # γ - a54 - btilde5 = -γ - c3 = convert(T2, 0.468238744853136) - c4 = convert(T2, 1) - α21 = convert(T2, 2) # c2/γ - α31 = convert(T2, 0.462864521870446) - α32 = convert(T2, 0.537135478129554) - α41 = convert(T2, -0.14714018016178376) - α42 = convert(T2, 1.1471401801617838) - Kvaerno4Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, - btilde1, btilde2, btilde3, btilde4, btilde5, - c3, c4, α21, α31, α32, α41, α42) -end - -struct KenCarp4Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a63::T - a64::T - a65::T - btilde1::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - c3::T2 - c4::T2 - c5::T2 - α21::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 - α51::T2 - α52::T2 - α53::T2 - α54::T2 - α61::T2 - α62::T2 - α63::T2 - α64::T2 - α65::T2 - ea21::T - ea31::T - ea32::T - ea41::T - ea42::T - ea43::T - ea51::T - ea52::T - ea53::T - ea54::T - ea61::T - ea62::T - ea63::T - ea64::T - ea65::T - eb1::T - eb3::T - eb4::T - eb5::T - eb6::T - ebtilde1::T - ebtilde3::T - ebtilde4::T - ebtilde5::T - ebtilde6::T -end - -struct CFNLIRK3Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - c2::T2 - c3::T2 - ea21::T - ea31::T - ea32::T - ea41::T - ea42::T - ea43::T - eb1::T - eb2::T - eb3::T - eb4::T -end - -function CFNLIRK3Tableau(T, T2) - #Implicit Tableau - γ = convert(T2, 0.43586652150846) - a31 = convert(T, 0.0) - a32 = convert(T, (1 - γ) / 2) - a41 = convert(T, 0.0) - a42 = convert(T, 1.20849664917601276) - a43 = convert(T, -0.64436317068447276) - c3 = (1 + γ) / 2 - c2 = γ - - # Explicit Tableau - ea21 = convert(T, γ) - ea31 = convert(T, (1.7 + γ) / 2) - ea32 = convert(T, -0.35) - ea41 = convert(T, 0.0) - ea42 = convert(T, 1.9891757246798590) - ea43 = convert(T, -0.9891757246798590) - eb1 = convert(T, 0.0) - eb2 = convert(T, 1.20849664917601276) - eb3 = convert(T, -0.64436317068447276) - eb4 = convert(T, γ) - CFNLIRK3Tableau(γ, a31, a32, a41, a42, a43, c2, c3, ea21, ea31, ea32, ea41, ea42, ea43, - eb1, eb2, eb3, eb4) -end - -#= -# KenCarp4 -# Predict z3 from Hermite z2 and z1 - -c2 = 2γ -θ = c3/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z4 from Hermite z2 and z1 -θ = c4/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z5 from Hermite z2 and z1 -θ = c5/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z5 from z1 and z4 - -θ = c5/c4 -dt = c4 - -y₀ = uprev -y₁ = uprev + a41*z₁ + a42*z₂ + a43*z₃ + γ*z₄ -y₁-y₀ = a41*z₁ + a42*z₂ + a43*z₃ + γ*z₄ - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₅ -+ (6θ*(1-θ)/dt)*(a52*z₂ + a53*z₃ + a54*z₄) - -(1 + (-4θ + 3θ^2) + a41*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a42 -(6θ*(1-θ)/dt)*a43 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -# Predict last stage from z1 and z5 - -θ = 1/c5 -dt = c5 - -y₀ = uprev -y₁ = uprev + a51*z₁ + a52*z₂ + a53*z₃ + a54*z₄ + γ*z₅ -y₁-y₀ = a51*z₁ + a52*z₂ + a53*z₃ + a54*z₄ + γ*z₅ - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₅ -+ (6θ*(1-θ)/dt)*(a52*z₂ + a53*z₃ + a54*z₄) - -(1 + (-4θ + 3θ^2) + a51*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a52 -(6θ*(1-θ)/dt)*a53 -(6θ*(1-θ)/dt)*a54 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -=# -function KenCarp4Tableau(T, T2) - γ = convert(T2, 1 // 4) - a31 = convert(T, 8611 // 62500) - a32 = -convert(T, 1743 // 31250) - a41 = convert(T, 5012029 // 34652500) - a42 = -convert(T, 654441 // 2922500) - a43 = convert(T, 174375 // 388108) - a51 = convert(T, 15267082809 // 155376265600) - a52 = -convert(T, 71443401 // 120774400) - a53 = convert(T, 730878875 // 902184768) - a54 = convert(T, 2285395 // 8070912) - a61 = convert(T, 82889 // 524892) - a63 = convert(T, 15625 // 83664) - a64 = convert(T, 69875 // 102672) - a65 = -convert(T, 2260 // 8211) - # bhat1 = convert(T,4586570599//29645900160) - # bhat3 = convert(T,178811875//945068544) - # bhat4 = convert(T,814220225//1159782912) - # bhat5 = -convert(T,3700637//11593932) - # bhat6 = convert(T,61727//225920) - btilde1 = convert(T, -31666707 // 9881966720) # bhat1-a61 - btilde3 = convert(T, 256875 // 105007616) # bhat3-a63 - btilde4 = convert(T, 2768025 // 128864768) # bhat4-a64 - btilde5 = convert(T, -169839 // 3864644) # bhat5-a65 - btilde6 = convert(T, 5247 // 225920) # bhat6-γ - c3 = convert(T2, 83 // 250) - c4 = convert(T2, 31 // 50) - c5 = convert(T2, 17 // 20) - α21 = convert(T2, 2) # c2/γ - α31 = convert(T2, 42 // 125) - α32 = convert(T2, 83 // 125) - α41 = convert(T2, -6 // 25) - α42 = convert(T2, 31 // 25) - α51 = convert(T2, 914470432 // 2064665255) - α52 = convert(T2, 798813 // 724780) - α53 = convert(T2, -824765625 // 372971788) - α54 = convert(T2, 49640 // 29791) - α61 = convert(T2, 288521442795 // 954204491116) - α62 = convert(T2, 2224881 // 2566456) - α63 = convert(T2, -1074821875 // 905317354) - α64 = convert(T2, -3360875 // 8098936) - α65 = convert(T2, 7040 // 4913) - - ea21 = convert(T, 1 // 2) - ea31 = convert(T, 13861 // 62500) - ea32 = convert(T, 6889 // 62500) - ea41 = -convert(T, 116923316275 // 2393684061468) - ea42 = -convert(T, 2731218467317 // 15368042101831) - ea43 = convert(T, 9408046702089 // 11113171139209) - ea51 = -convert(T, 451086348788 // 2902428689909) - ea52 = -convert(T, 2682348792572 // 7519795681897) - ea53 = convert(T, 12662868775082 // 11960479115383) - ea54 = convert(T, 3355817975965 // 11060851509271) - ea61 = convert(T, 647845179188 // 3216320057751) - ea62 = convert(T, 73281519250 // 8382639484533) - ea63 = convert(T, 552539513391 // 3454668386233) - ea64 = convert(T, 3354512671639 // 8306763924573) - ea65 = convert(T, 4040 // 17871) - - eb1 = convert(T, 82889 // 524892) - eb3 = convert(T, 15625 // 83664) - eb4 = convert(T, 69875 // 102672) - eb5 = -convert(T, 2260 // 8211) - eb6 = convert(T, 1 // 4) - - ebtilde1 = -convert(T, 31666707 // 9881966720) - ebtilde3 = convert(T, 256875 // 105007616) - ebtilde4 = convert(T, 2768025 // 128864768) - ebtilde5 = -convert(T, 169839 // 3864644) - ebtilde6 = convert(T, 5247 // 225920) - - KenCarp4Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a63, a64, a65, - btilde1, btilde3, btilde4, btilde5, btilde6, - c3, c4, c5, - α21, α31, α32, α41, α42, α51, α52, α53, α54, α61, α62, α63, α64, α65, - ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, - ea63, ea64, ea65, eb1, eb3, eb4, eb5, eb6, ebtilde1, ebtilde3, ebtilde4, - ebtilde5, ebtilde6) -end - -# Flip them all! - -# ebtilde1 = 82889//524892 - 4586570599//29645900160 -# ebtilde3 = 15625//83664 - 178811875//945068544 -# ebtilde4 = 69875//102672 - 814220225//1159782912 -# ebtilde5 = -2260//8211 + 3700637//11593932 -# ebtilde6 = 1//4 - 61727//225920 - -struct Kvaerno5Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a63::T - a64::T - a65::T - a71::T - a73::T - a74::T - a75::T - a76::T - btilde1::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 - α43::T2 - α51::T2 - α52::T2 - α53::T2 - α61::T2 - α62::T2 - α63::T2 -end - -#= -# Kvaerno5 -# Predict z3 from Hermite z2 and z1 - -c2 = 2γ -θ = c3/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict others from z1 and z3 since it covers [0,1.23] - -dt = c3 since interval is [c1,c3] and c1 = 0 -θ = c4/c3, c5/c3, c6/c3, c7/c3 -z = dt*k - -z₁ + Θ*(-4dt*z₁ - 2dt*z₃ - 6y₀ + Θ*(3dt*z₁ + 3z₃ + 6y₀ - 6y₁ ) + 6y₁)/dt - -(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) - -y₀ = uprev -y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ -y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ + (6θ*(1-θ)/dt)*a32*z₂ - -dt = c3 -θ = c4/c3 -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a32 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -θ = c5/c3 -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a32 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -θ = c6/c3 -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a32 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) -=# - -function Kvaerno5Tableau(T, T2) - γ = convert(T2, 0.26) - a31 = convert(T, 0.13) - a32 = convert(T, 0.84033320996790809) - a41 = convert(T, 0.22371961478320505) - a42 = convert(T, 0.47675532319799699) - a43 = -convert(T, 0.06470895363112615) - a51 = convert(T, 0.16648564323248321) - a52 = convert(T, 0.10450018841591720) - a53 = convert(T, 0.03631482272098715) - a54 = -convert(T, 0.13090704451073998) - a61 = convert(T, 0.13855640231268224) - a63 = -convert(T, 0.04245337201752043) - a64 = convert(T, 0.02446657898003141) - a65 = convert(T, 0.61943039072480676) - a71 = convert(T, 0.13659751177640291) - a73 = -convert(T, 0.05496908796538376) - a74 = -convert(T, 0.04118626728321046) - a75 = convert(T, 0.62993304899016403) - a76 = convert(T, 0.06962479448202728) - btilde1 = convert(T, 0.00195889053627933) # a61-a71 - btilde3 = convert(T, 0.01251571594786333) # a63-a73 - btilde4 = convert(T, 0.06565284626324187) # a64-a74 - btilde5 = -convert(T, 0.01050265826535727) # a65-a75 - btilde6 = convert(T, 0.19037520551797272) # γ-a76 - btilde7 = -γ - α21 = convert(T, 2) # c2/γ - α31 = convert(T2, -1.366025403784441) - α32 = convert(T2, 2.3660254037844357) - α41 = convert(T2, -0.19650552613122207) - α42 = convert(T2, 0.8113579546496623) - α43 = convert(T2, 0.38514757148155954) - α51 = convert(T2, 0.10375304369958693) - α52 = convert(T2, 0.937994698066431) - α53 = convert(T2, -0.04174774176601781) - α61 = convert(T2, -0.17281112873898072) - α62 = convert(T2, 0.6235784481025847) - α63 = convert(T2, 0.5492326806363959) - c3 = convert(T, 1.230333209967908) - c4 = convert(T, 0.895765984350076) - c5 = convert(T, 0.436393609858648) - c6 = convert(T, 1) - Kvaerno5Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, - a61, a63, a64, a65, a71, a73, a74, a75, a76, - btilde1, btilde3, btilde4, btilde5, btilde6, btilde7, - c3, c4, c5, c6, α31, α32, α41, α42, α43, α51, α52, α53, - α61, α62, α63) -end - -struct KenCarp5Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a43::T - a51::T - a53::T - a54::T - a61::T - a63::T - a64::T - a65::T - a71::T - a73::T - a74::T - a75::T - a76::T - a81::T - a84::T - a85::T - a86::T - a87::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 - α51::T2 - α52::T2 - α61::T2 - α62::T2 - α71::T2 - α72::T2 - α73::T2 - α74::T2 - α75::T2 - α81::T2 - α82::T2 - α83::T2 - α84::T2 - α85::T2 - btilde1::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - btilde8::T - ea21::T - ea31::T - ea32::T - ea41::T - ea43::T - ea51::T - ea53::T - ea54::T - ea61::T - ea63::T - ea64::T - ea65::T - ea71::T - ea73::T - ea74::T - ea75::T - ea76::T - ea81::T - ea83::T - ea84::T - ea85::T - ea86::T - ea87::T - eb1::T - eb4::T - eb5::T - eb6::T - eb7::T - eb8::T - ebtilde1::T - ebtilde4::T - ebtilde5::T - ebtilde6::T - ebtilde7::T - ebtilde8::T -end - -#= -# KenCarp5 -# Predict z3 from Hermite z2 and z1 - -c2 = 2γ -θ = c3/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z4 from z2 and z1 -θ = c4/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z5 from z2 and z1 -θ = c5/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z6 from z2 and z1 -θ = c6/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z7 from z5 and z1 -θ = c7/c5 -dt = c5 - -(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) -y₁-y₀ = a51*z₁ + a52*z₂ + a53*z₃ + a54*z₄ + γ*z₅ - -(1 + (-4θ + 3θ^2) + a51*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a52 -(6θ*(1-θ)/dt)*a53 -(6θ*(1-θ)/dt)*a54 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -# Predict z8 from z5 and z1 -θ = 1/c5 -dt = c5 - -(1 + (-4θ + 3θ^2) + a51*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a52 -(6θ*(1-θ)/dt)*a53 -(6θ*(1-θ)/dt)*a54 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -=# - -function KenCarp5Tableau(T, T2) - γ = convert(T2, 41 // 200) - a31 = convert(T, 41 // 400) - a32 = -convert(T, 567603406766 // 11931857230679) - a41 = convert(T, 683785636431 // 9252920307686) - a43 = -convert(T, 110385047103 // 1367015193373) - a51 = convert(T, 3016520224154 // 10081342136671) - a53 = convert(T, 30586259806659 // 12414158314087) - a54 = -convert(T, 22760509404356 // 11113319521817) - a61 = convert(T, 218866479029 // 1489978393911) - a63 = convert(T, 638256894668 // 5436446318841) - a64 = -convert(T, 1179710474555 // 5321154724896) - a65 = -convert(T, 60928119172 // 8023461067671) - a71 = convert(T, 1020004230633 // 5715676835656) - a73 = convert(T, 25762820946817 // 25263940353407) - a74 = -convert(T, 2161375909145 // 9755907335909) - a75 = -convert(T, 211217309593 // 5846859502534) - a76 = -convert(T, 4269925059573 // 7827059040749) - a81 = -convert(T, 872700587467 // 9133579230613) - a84 = convert(T, 22348218063261 // 9555858737531) - a85 = -convert(T, 1143369518992 // 8141816002931) - a86 = -convert(T, 39379526789629 // 19018526304540) - a87 = convert(T, 32727382324388 // 42900044865799) - # bhat1 = -convert(T,975461918565//9796059967033) - # bhat4 = convert(T,78070527104295//32432590147079) - # bhat5 = -convert(T,548382580838//3424219808633) - # bhat6 = -convert(T,33438840321285//15594753105479) - # bhat7 = convert(T,3629800801594//4656183773603) - # bhat8 = convert(T,4035322873751//18575991585200) - btilde1 = -convert(T, 360431431567533808054934 // 89473089856732078284381229) # bhat1-a81 - btilde4 = convert(T, 21220331609936495351431026 // 309921249937726682547321949) # bhat4-a84 - btilde5 = -convert(T, 42283193605833819490634 // 2144566741190883522084871) # bhat5-a85 - btilde6 = -convert(T, 21843466548811234473856609 // 296589222149359214696574660) # bhat6-a86 - btilde7 = convert(T, 3333910710978735057753642 // 199750492790973993533703797) # bhat7-a87 - btilde8 = convert(T, 45448919757 // 3715198317040) # bhat8-γ - c3 = convert(T2, 2935347310677 // 11292855782101) - c4 = convert(T2, 1426016391358 // 7196633302097) - c5 = convert(T2, 92 // 100) - c6 = convert(T2, 24 // 100) - c7 = convert(T2, 3 // 5) - α31 = convert(T2, 169472355998441 // 463007087066141) - α32 = convert(T2, 293534731067700 // 463007087066141) - α41 = convert(T2, 152460326250177 // 295061965385977) - α42 = convert(T2, 142601639135800 // 295061965385977) - α51 = convert(T2, -51 // 41) - α52 = convert(T2, 92 // 41) - α61 = convert(T2, 17 // 41) - α62 = convert(T2, 24 // 41) - α71 = convert(T2, 13488091065527792 // 122659689776876057) - α72 = convert(T2, -3214953045 // 3673655312) - α73 = convert(T2, 550552676519862000 // 151043064207496529) - α74 = convert(T2, -409689169278408000 // 135215758621947439) - α75 = convert(T2, 3345 // 12167) - α81 = convert(T2, 1490668709762032 // 122659689776876057) - α82 = convert(T2, 5358255075 // 14694621248) - α83 = convert(T2, -229396948549942500 // 151043064207496529) - α84 = convert(T2, 170703820532670000 // 135215758621947439) - α85 = convert(T2, 30275 // 24334) - - ea21 = convert(T, 41 // 100) - ea31 = convert(T, 367902744464 // 2072280473677) - ea32 = convert(T, 677623207551 // 8224143866563) - ea41 = convert(T, 1268023523408 // 10340822734521) - ea43 = convert(T, 1029933939417 // 13636558850479) - ea51 = convert(T, 14463281900351 // 6315353703477) - ea53 = convert(T, 66114435211212 // 5879490589093) - ea54 = -convert(T, 54053170152839 // 4284798021562) - ea61 = convert(T, 14090043504691 // 34967701212078) - ea63 = convert(T, 15191511035443 // 11219624916014) - ea64 = -convert(T, 18461159152457 // 12425892160975) - ea65 = -convert(T, 281667163811 // 9011619295870) - ea71 = convert(T, 19230459214898 // 13134317526959) - ea73 = convert(T, 21275331358303 // 2942455364971) - ea74 = -convert(T, 38145345988419 // 4862620318723) - ea75 = -convert(T, 1 // 8) - ea76 = -convert(T, 1 // 8) - ea81 = -convert(T, 19977161125411 // 11928030595625) - ea83 = -convert(T, 40795976796054 // 6384907823539) - ea84 = convert(T, 177454434618887 // 12078138498510) - ea85 = convert(T, 782672205425 // 8267701900261) - ea86 = -convert(T, 69563011059811 // 9646580694205) - ea87 = convert(T, 7356628210526 // 4942186776405) - - eb1 = -convert(T, 872700587467 // 9133579230613) - eb4 = convert(T, 22348218063261 // 9555858737531) - eb5 = -convert(T, 1143369518992 // 8141816002931) - eb6 = -convert(T, 39379526789629 // 19018526304540) - eb7 = convert(T, 32727382324388 // 42900044865799) - eb8 = convert(T, 41 // 200) - - ebtilde1 = -convert(T, 360431431567533808054934 // 89473089856732078284381229) - ebtilde4 = convert(T, 21220331609936495351431026 // 309921249937726682547321949) - ebtilde5 = -convert(T, 42283193605833819490634 // 2144566741190883522084871) - ebtilde6 = -convert(T, 21843466548811234473856609 // 296589222149359214696574660) - ebtilde7 = convert(T, 3333910710978735057753642 // 199750492790973993533703797) - ebtilde8 = convert(T, 45448919757 // 3715198317040) - - KenCarp5Tableau(γ, a31, a32, a41, a43, a51, a53, a54, a61, a63, a64, a65, - a71, a73, a74, a75, a76, a81, a84, a85, a86, a87, - c3, c4, c5, c6, c7, α31, α32, α41, α42, α51, α52, - α61, α62, α71, α72, α73, α74, α75, α81, α82, α83, α84, α85, - btilde1, btilde4, btilde5, btilde6, btilde7, btilde8, - ea21, ea31, ea32, ea41, ea43, ea51, ea53, ea54, ea61, ea63, - ea64, ea65, ea71, ea73, ea74, ea75, ea76, ea81, ea83, ea84, - ea85, ea86, ea87, eb1, eb4, eb5, eb6, eb7, eb8, ebtilde1, - ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8) -end - -# Flip them all! - -# ebtilde1 = -Int128(872700587467)//9133579230613 + Int128(975461918565)//9796059967033 -# ebtilde4 = Int128(22348218063261)//9555858737531 - Int128(78070527104295)//32432590147079 -# ebtilde5 = -Int128(1143369518992)//8141816002931 + Int128(548382580838)//3424219808633 -# ebtilde6 = -Int128(39379526789629)//19018526304540 + Int128(33438840321285)//15594753105479 -# ebtilde7 = Int128(32727382324388)//42900044865799 - Int128(3629800801594)//4656183773603 -# ebtilde8 = Int128(41)//200 - Int128(4035322873751)//18575991585200 - -struct ESDIRK54I8L2SATableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - a81::T - a82::T - a83::T - a84::T - a85::T - a86::T - a87::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - btilde8::T -end - -function ESDIRK54I8L2SATableau(T, T2) - γ = convert(T2, 1 // 4) - a31 = convert(T, 1748874742213 // 5795261096931) - a32 = convert(T, 1748874742213 // 5795261096931) - a41 = convert(T, 2426486750897 // 12677310711630) - a42 = convert(T, 2426486750897 // 12677310711630) - a43 = convert(T, -783385356511 // 7619901499812) - a51 = convert(T, 1616209367427 // 5722977998639) - a52 = convert(T, 1616209367427 // 5722977998639) - a53 = convert(T, -211896077633 // 5134769641545) - a54 = convert(T, 464248917192 // 17550087120101) - a61 = convert(T, 1860464898611 // 7805430689312) - a62 = convert(T, 1825204367749 // 7149715425471) - a63 = convert(T, -1289376786583 // 6598860380111) - a64 = convert(T, 55566826943 // 2961051076052) - a65 = convert(T, 1548994872005 // 13709222415197) - a71 = convert(T, 1783640092711 // 14417713428467) - a72 = convert(T, -5781183663275 // 18946039887294) - a73 = convert(T, -57847255876685 // 10564937217081) - a74 = convert(T, 29339178902168 // 9787613280015) - a75 = convert(T, 122011506936853 // 12523522131766) - a76 = convert(T, -60418758964762 // 9539790648093) - a81 = convert(T, 3148564786223 // 23549948766475) - a82 = convert(T, -4152366519273 // 20368318839251) - a83 = convert(T, -143958253112335 // 33767350176582) - a84 = convert(T, 16929685656751 // 6821330976083) - a85 = convert(T, 37330861322165 // 4907624269821) - a86 = convert(T, -103974720808012 // 20856851060343) - a87 = convert(T, -93596557767 // 4675692258479) - c3 = convert(T2, (2 + sqrt(convert(T, 2))) / 4) - c4 = convert(T2, 53 // 100) - c5 = convert(T2, 4 // 5) - c6 = convert(T2, 17 // 25) - c7 = convert(T2, 1) - btilde1 = convert(T, -206948709334490044469698 // 10480001459192469358387375) - btilde2 = convert(T, -38800234036520698435148405 // 193732560740235652447264213) - btilde3 = convert(T, -42312118141829119927717945 // 17651296211698462951718982) - btilde4 = convert(T, 77601425937783402908082927 // 76091823354023603930374324) - btilde5 = convert(T, 7549135156215231570800855 // 1787280796764804347348433) - btilde6 = convert(T, -401514321964993460839314379 // 150599863859115530598736650) - btilde7 = convert(T, 17761325247710183915293664 // 33262552787523086832167825) - btilde8 = convert(T, -25249389576073 // 51072051291964) - ESDIRK54I8L2SATableau(γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - a81, a82, a83, a84, a85, a86, a87, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, - btilde8) -end - -struct ESDIRK436L2SA2Tableau{T, T2} - γ::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T -end - -function ESDIRK436L2SA2Tableau(T, T2) - γ = convert(T, 31 // 125) - a31 = convert(T, -360286518617 // 7014585480527) - a32 = convert(T, -360286518617 // 7014585480527) - a41 = convert(T, -506388693497 // 5937754990171) - a42 = convert(T, -506388693497 // 5937754990171) - a43 = convert(T, 7149918333491 // 13390931526268) - a51 = convert(T, -7628305438933 // 11061539393788) - a52 = convert(T, -7628305438933 // 11061539393788) - a53 = convert(T, 21592626537567 // 14352247503901) - a54 = convert(T, 11630056083252 // 17263101053231) - a61 = convert(T, -12917657251 // 5222094901039) - a62 = convert(T, -12917657251 // 5222094901039) - a63 = convert(T, 5602338284630 // 15643096342197) - a64 = convert(T, 9002339615474 // 18125249312447) - a65 = convert(T, -2420307481369 // 24731958684496) - c3 = convert(T2, 486119545908 // 3346201505189) - c4 = convert(T2, 1043 // 1706) - c5 = convert(T2, 1361 // 1300) - c6 = convert(T2, 1) - btilde1 = convert(T, 5106873525203549881053916 // 63280437666689274586070553) - btilde2 = convert(T, 5106873525203549881053916 // 63280437666689274586070553) - btilde3 = convert(T, -25162027003603428150355757 // 187362381104177276978781327) - btilde4 = convert(T, -4098711186040344850920813 // 204021751328880889263048263) - btilde5 = convert(T, -2403006641348284599749077 // 92621941821407359153398928) - btilde6 = convert(T, 20990421664717 // 1109114971657125) - ESDIRK436L2SA2Tableau(γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - c3, c4, c5, c6, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6) -end - -struct ESDIRK437L2SATableau{T, T2} - γ::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T -end - -function ESDIRK437L2SATableau(T, T2) - γ = convert(T, 1 // 8) - a31 = convert(T, -39188347878 // 1513744654945) - a32 = convert(T, -39188347878 // 1513744654945) - a41 = convert(T, 1748874742213 // 5168247530883) - a42 = convert(T, 1748874742213 // 5168247530883) - a43 = convert(T, -1748874742213 // 5795261096931) - a51 = convert(T, -6429340993097 // 17896796106705) - a52 = convert(T, -6429340993097 // 17896796106705) - a53 = convert(T, 9711656375562 // 10370074603625) - a54 = convert(T, 1137589605079 // 3216875020685) - a61 = convert(T, 405169606099 // 1734380148729) - a62 = convert(T, 405169606099 // 1734380148729) - a63 = convert(T, -264468840649 // 6105657584947) - a64 = convert(T, 118647369377 // 6233854714037) - a65 = convert(T, 683008737625 // 4934655825458) - a71 = convert(T, -5649241495537 // 14093099002237) - a72 = convert(T, -5649241495537 // 14093099002237) - a73 = convert(T, 5718691255176 // 6089204655961) - a74 = convert(T, 2199600963556 // 4241893152925) - a75 = convert(T, 8860614275765 // 11425531467341) - a76 = convert(T, -3696041814078 // 6641566663007) - c3 = convert(T2, 1200237871921 // 16391473681546) - c4 = convert(T2, 1 // 2) - c5 = convert(T2, 395 // 567) - c6 = convert(T2, 89 // 126) - c7 = convert(T2, 1) - btilde1 = convert(T, -14021722784906200638478406 / 88328749927055336625976631) - btilde2 = convert(T, -14021722784906200638478406 / 88328749927055336625976631) - btilde3 = convert(T, 3070711560882459617262660 / 10949513763298336699947229) - btilde4 = convert(T, 815814787991699828720304 / 45161095659596754702440075) - btilde5 = convert(T, 1195088015805686578873824 / 81172597762810000486866617) - btilde6 = convert(T, 740420675674591594133033 / 49448254888661947436093061) - btilde7 = convert(T, -3 / 280) - ESDIRK437L2SATableau(γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) -end - -struct ESDIRK547L2SA2Tableau{T, T2} - γ::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T -end - -function ESDIRK547L2SA2Tableau(T, T2) - γ = convert(T, 23 // 125) - a31 = convert(T, 791020047304 // 3561426431547) - a32 = convert(T, 791020047304 // 3561426431547) - a41 = convert(T, -158159076358 // 11257294102345) - a42 = convert(T, -158159076358 // 11257294102345) - a43 = convert(T, -85517644447 // 5003708988389) - a51 = convert(T, -1653327111580 // 4048416487981) - a52 = convert(T, -1653327111580 // 4048416487981) - a53 = convert(T, 1514767744496 // 9099671765375) - a54 = convert(T, 14283835447591 // 12247432691556) - a61 = convert(T, -4540011970825 // 8418487046959) - a62 = convert(T, -4540011970825 // 8418487046959) - a63 = convert(T, -1790937573418 // 7393406387169) - a64 = convert(T, 10819093665085 // 7266595846747) - a65 = convert(T, 4109463131231 // 7386972500302) - a71 = convert(T, -188593204321 // 4778616380481) - a72 = convert(T, -188593204321 // 4778616380481) - a73 = convert(T, 2809310203510 // 10304234040467) - a74 = convert(T, 1021729336898 // 2364210264653) - a75 = convert(T, 870612361811 // 2470410392208) - a76 = convert(T, -1307970675534 // 8059683598661) - c3 = convert(T2, 7121331996143 // 11335814405378) - c4 = convert(T2, 49 // 453) - c5 = convert(T2, 3706679970760 // 5295570149437) - c6 = convert(T2, 347 // 382) - c7 = convert(T2, 1) - btilde1 = convert(T, 1421105133983177175480607 // 34473265709570096426728110) - btilde2 = convert(T, 1421105133983177175480607 // 34473265709570096426728110) - btilde3 = convert(T, 3109316704168648469186161 // 34649291136493354414563315) - btilde4 = convert(T, -1238536018553705945740781 // 14596994419085808131818547) - btilde5 = convert(T, -2644586096629232150947109 // 35649179736979632279017232) - btilde6 = convert(T, -4528233948360460577182037 // 78128560886623254313643924) - btilde7 = convert(T, 77036761781598 // 1719282803550125) - ESDIRK547L2SA2Tableau(γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - c3, c4, c5, c6, c7, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7) -end - -struct ESDIRK659L2SATableau{T, T2} - γ::T - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - a81::T - a82::T - a83::T - a84::T - a85::T - a86::T - a87::T - a94::T - a95::T - a96::T - a97::T - a98::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - c8::T2 - c9::T2 - btilde1::T - btilde2::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - btilde8::T - btilde9::T -end - -function ESDIRK659L2SATableau(T, T2) - γ = convert(T, 2 // 9) - a31 = convert(T, 1 // 9) - a32 = convert(T, -52295652026801 // 1014133226193379) - a41 = convert(T, 37633260247889 // 456511413219805) - a42 = convert(T, -162541608159785 // 642690962402252) - a43 = convert(T, 186915148640310 // 408032288622937) - a51 = convert(T, -37161579357179 // 532208945751958) - a52 = convert(T, -211140841282847 // 266150973773621) - a53 = convert(T, 884359688045285 // 894827558443789) - a54 = convert(T, 845261567597837 // 1489150009616527) - a61 = convert(T, 32386175866773 // 281337331200713) - a62 = convert(T, 498042629717897 // 1553069719539220) - a63 = convert(T, -73718535152787 // 262520491717733) - a64 = convert(T, -147656452213061 // 931530156064788) - a65 = convert(T, -16605385309793 // 2106054502776008) - a71 = convert(T, -38317091100349 // 1495803980405525) - a72 = convert(T, 233542892858682 // 880478953581929) - a73 = convert(T, -281992829959331 // 709729395317651) - a74 = convert(T, -52133614094227 // 895217507304839) - a75 = convert(T, -9321507955616 // 673810579175161) - a76 = convert(T, 79481371174259 // 817241804646218) - a81 = convert(T, -486324380411713 // 1453057025607868) - a82 = convert(T, -1085539098090580 // 1176943702490991) - a83 = convert(T, 370161554881539 // 461122320759884) - a84 = convert(T, 804017943088158 // 886363045286999) - a85 = convert(T, -15204170533868 // 934878849212545) - a86 = convert(T, -248215443403879 // 815097869999138) - a87 = convert(T, 339987959782520 // 552150039467091) - a94 = convert(T, 281246836687281 // 672805784366875) - a95 = convert(T, 250674029546725 // 464056298040646) - a96 = convert(T, 88917245119922 // 798581755375683) - a97 = convert(T, 127306093275639 // 658941305589808) - a98 = convert(T, -319515475352107 // 658842144391777) - c3 = convert(T2, 376327483029687 // 1335600577485745) - c4 = convert(T2, 433625707911282 // 850513180247701) - c5 = convert(T2, 183 // 200) - c6 = convert(T2, 62409086037595 // 296036819031271) - c7 = convert(T2, 81796628710131 // 911762868125288) - c8 = convert(T2, 97 // 100) - c9 = convert(T2, 1) - btilde1 = convert(T, 204006714482445 // 253120897457864) - btilde2 = convert(T, 0) - btilde3 = convert(T, 818062434310719 // 743038324242217) - btilde4 = convert(T, -4352947315360352 // 1695885076290837) - btilde5 = convert(T, 4343240072384756 // 4531602892210441) - btilde6 = convert(T, 3512964806614449 // 5680260981303268) - btilde7 = convert(T, -8547437843719087 // 4555265955453704) - btilde8 = convert(T, -6600542869175559 // 6801491069014681) - btilde9 = convert(T, 1602386750057009 // 6720377925948840) - ESDIRK659L2SATableau(γ, - a31, a32, - a41, a42, a43, - a51, a52, a53, a54, - a61, a62, a63, a64, a65, - a71, a72, a73, a74, a75, a76, - a81, a82, a83, a84, a85, a86, a87, - a94, a95, a96, a97, a98, - c3, c4, c5, c6, c7, c8, c9, - btilde1, btilde2, btilde3, btilde4, btilde5, btilde6, btilde7, - btilde8, btilde9) -end - -struct SDIRK22Tableau{T} - a::T - α::T - β::T -end - -function SDIRK22Tableau(T) - a = convert(T, 1 - 1 / sqrt(2)) - α = convert(T, -sqrt(2)) - β = convert(T, 1 + sqrt(2)) - SDIRK22Tableau(a, α, β) -end - -struct KenCarp47Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a73::T - a74::T - a75::T - a76::T - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - α21::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 - α43::T2 - α51::T2 - α52::T2 - α61::T2 - α62::T2 - α63::T2 - α71::T2 - α72::T2 - α73::T2 - α74::T2 - α75::T2 - α76::T2 - ea21::T - ea31::T - ea32::T - ea41::T - ea42::T - ea43::T - ea51::T - ea52::T - ea53::T - ea54::T - ea61::T - ea62::T - ea63::T - ea64::T - ea65::T - ea71::T - ea72::T - ea73::T - ea74::T - ea75::T - ea76::T - eb3::T - eb4::T - eb5::T - eb6::T - eb7::T - ebtilde3::T - ebtilde4::T - ebtilde5::T - ebtilde6::T - ebtilde7::T -end - -#= -# KenCarp47 -# Predict z3 from Hermite z2 and z1 - -c2 = 2γ -θ = c3/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z4 from Hermite z3 and z1 -θ = c4/c3 -dt = c3 - -y₀ = uprev -y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ -y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ -+ (6θ*(1-θ)/dt)*(a32*z₂) - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a32 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -# Predict z5 from Hermite z2 and z1 -θ = c5/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z6 from z1 and z3 - -θ = c6/c3 -dt = c3 - -y₀ = uprev -y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ -y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ -+ (6θ*(1-θ)/dt)*(a32*z₂) - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a32 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -Predict last stage from z1 and z6 - -θ = 1/c6 -dt = c6 - -y₀ = uprev -y₁ = uprev + a61*z₁ + a62*z₂ + a63*z₃ + a64*z₄ + a65*z₅ + γ*z₆ -y₁-y₀ = a61*z₁ + a62*z₂ + a63*z₃ + a64*z₄ + a65*z₅ + γ*z₆ - -(1 + (-4θ + 3θ^2) + a61*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₆ -+ (6θ*(1-θ)/dt)*(a62*z₂ + a63*z₃ + a64*z₄ + a65*z₅) - -(1 + (-4θ + 3θ^2) + a61*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a62 -(6θ*(1-θ)/dt)*a63 -(6θ*(1-θ)/dt)*a64 -(6θ*(1-θ)/dt)*a65 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -=# -function KenCarp47Tableau(T, T2) - γ = convert(T2, 1235 // 10000) - a31 = convert(T, 624185399699 // 4186980696204) - a32 = a31 - a41 = convert(T, 1258591069120 // 10082082980243) - a42 = a41 - a43 = -convert(T, 322722984531 // 8455138723562) - a51 = -convert(T, 436103496990 // 5971407786587) - a52 = a51 - a53 = -convert(T, 2689175662187 // 11046760208243) - a54 = convert(T, 4431412449334 // 12995360898505) - a61 = -convert(T, 2207373168298 // 14430576638973) - a62 = a61 - a63 = convert(T, 242511121179 // 3358618340039) - a64 = convert(T, 3145666661981 // 7780404714551) - a65 = convert(T, 5882073923981 // 14490790706663) - #a71 = convert(T,0) - #a72 = convert(T,0) - a73 = convert(T, 9164257142617 // 17756377923965) - a74 = -convert(T, 10812980402763 // 74029279521829) - a75 = convert(T, 1335994250573 // 5691609445217) - a76 = convert(T, 2273837961795 // 8368240463276) - - # bhat3 = convert(T,4469248916618//8635866897933) - # bhat4 = -convert(T,621260224600//4094290005349) - # bhat5 = convert(T,696572312987//2942599194819) - # bhat6 = convert(T,1532940081127//5565293938103) - # bhat7 = convert(T,2441//20000) - btilde3 = convert(T, 216367897668138065439709 // 153341716340757627089664345) # bhat3-a73 - btilde4 = -convert(T, 1719969231640509698414113 // 303097339249411872572263321) # bhat4-a74 - btilde5 = convert(T, 33321949854538424751892 // 16748125370719759490730723) # bhat5-a75 - btilde6 = convert(T, 4033362550194444079469 // 1083063207508329376479196) # bhat6-a76 - btilde7 = -convert(T, 29 // 20000) # bhat7-γ - - #c2 = 2γ - c3 = convert(T2, 4276536705230 // 10142255878289) - c4 = convert(T2, 67 // 200) - c5 = convert(T2, 3 // 40) - c6 = convert(T2, 7 // 10) - - α21 = convert(T2, 2) # c2/γ - α31 = -convert(T2, 796131459065721 // 1125899906842624) - α32 = convert(T2, 961015682954173 // 562949953421312) - α41 = convert(T2, 139710975840363 // 2251799813685248) - α42 = convert(T2, 389969885861609 // 1125899906842624) - α43 = convert(T2, 2664298132243335 // 4503599627370496) - α51 = convert(T2, 6272219723949193 // 9007199254740992) - α52 = convert(T2, 2734979530791799 // 9007199254740992) - α61 = convert(T2, 42616678320173 // 140737488355328) - α62 = -convert(T2, 2617409280098421 // 1125899906842624) - α63 = convert(T2, 1701187880189829 // 562949953421312) - α71 = convert(T2, 4978493057967061 // 2251799813685248) - α72 = convert(T2, 7230365118049293 // 9007199254740992) - α73 = -convert(T2, 6826045129237249 // 18014398509481984) - α74 = -convert(T2, 2388848894891525 // 1125899906842624) - α75 = -convert(T2, 4796744191239075 // 2251799813685248) - α76 = convert(T2, 2946706549191323 // 1125899906842624) - - ea21 = convert(T, 247 // 1000) - ea31 = convert(T, 247 // 4000) - ea32 = convert(T, 2694949928731 // 7487940209513) - ea41 = convert(T, 464650059369 // 8764239774964) - ea42 = convert(T, 878889893998 // 2444806327765) - ea43 = -convert(T, 952945855348 // 12294611323341) - ea51 = convert(T, 476636172619 // 8159180917465) - ea52 = -convert(T, 1271469283451 // 7793814740893) - ea53 = -convert(T, 859560642026 // 4356155882851) - ea54 = convert(T, 1723805262919 // 4571918432560) - ea61 = convert(T, 6338158500785 // 11769362343261) - ea62 = -convert(T, 4970555480458 // 10924838743837) - ea63 = convert(T, 3326578051521 // 2647936831840) - ea64 = -convert(T, 880713585975 // 1841400956686) - ea65 = -convert(T, 1428733748635 // 8843423958496) - ea71 = convert(T, 760814592956 // 3276306540349) - ea72 = convert(T, 760814592956 // 3276306540349) - ea73 = -convert(T, 47223648122716 // 6934462133451) - ea74 = convert(T, 71187472546993 // 9669769126921) - ea75 = -convert(T, 13330509492149 // 9695768672337) - ea76 = convert(T, 11565764226357 // 8513123442827) - - #eb1 = 0 - #eb2 = 0 - eb3 = convert(T, 9164257142617 // 17756377923965) - eb4 = -convert(T, 10812980402763 // 74029279521829) - eb5 = convert(T, 1335994250573 // 5691609445217) - eb6 = convert(T, 2273837961795 // 8368240463276) - eb7 = convert(T, 247 // 2000) - - #ebtilde1 = 0 - #ebtilde2 = 0 - ebtilde3 = convert(T, 216367897668138065439709 // 153341716340757627089664345) - ebtilde4 = -convert(T, 1719969231640509698414113 // 303097339249411872572263321) - ebtilde5 = convert(T, 33321949854538424751892 // 16748125370719759490730723) - ebtilde6 = convert(T, 4033362550194444079469 // 1083063207508329376479196) - ebtilde7 = -convert(T, 29 // 20000) - - KenCarp47Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, a73, a74, a75, a76, - btilde3, btilde4, btilde5, btilde6, btilde7, - c3, c4, c5, c6, - α21, α31, α32, α41, α42, α43, α51, α52, α61, α62, α63, α71, α72, α73, - α74, α75, α76, - ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, - ea63, ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76, eb3, eb4, eb5, - eb6, eb7, ebtilde3, ebtilde4, - ebtilde5, ebtilde6, ebtilde7) -end -struct KenCarp58Tableau{T, T2} - γ::T2 - a31::T - a32::T - a41::T - a42::T - a43::T - a51::T - a52::T - a53::T - a54::T - a61::T - a62::T - a63::T - a64::T - a65::T - a71::T - a72::T - a73::T - a74::T - a75::T - a76::T - a83::T - a84::T - a85::T - a86::T - a87::T - c3::T2 - c4::T2 - c5::T2 - c6::T2 - c7::T2 - α31::T2 - α32::T2 - α41::T2 - α42::T2 - α51::T2 - α52::T2 - α61::T2 - α62::T2 - α63::T2 - α71::T2 - α72::T2 - α73::T2 - α81::T2 - α82::T2 - α83::T2 - α84::T2 - α85::T2 - α86::T2 - α87::T2 - btilde3::T - btilde4::T - btilde5::T - btilde6::T - btilde7::T - btilde8::T - ea21::T - ea31::T - ea32::T - ea41::T - ea42::T - ea43::T - ea51::T - ea52::T - ea53::T - ea54::T - ea61::T - ea62::T - ea63::T - ea64::T - ea65::T - ea71::T - ea72::T - ea73::T - ea74::T - ea75::T - ea76::T - ea81::T - ea82::T - ea83::T - ea84::T - ea85::T - ea86::T - ea87::T - eb3::T - eb4::T - eb5::T - eb6::T - eb7::T - eb8::T - ebtilde3::T - ebtilde4::T - ebtilde5::T - ebtilde6::T - ebtilde7::T - ebtilde8::T -end - -#= -# KenCarp5 -# Predict z3 from Hermite z2 and z1 - -c2 = 2γ -θ = c3/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z4 from z2 and z1 -θ = c4/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z5 from z2 and z1 -θ = c5/c2 -dt = c2 -((1 + (-4θ + 3θ^2)) + (6θ*(1-θ)/c2)*γ) -((-2θ + 3θ^2) + (6θ*(1-θ)/c2)*γ) - -# Predict z6 from z3 and z1 -θ = c6/c3 -dt = c3 - -y₀ = uprev -y₁ = uprev + a31*z₁ + a32*z₂ + γ*z₃ -y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ -+ (6θ*(1-θ)/dt)*(a32*z₂) - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a32 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -# Predict z7 from z3 and z1 -θ = c7/c3 -dt = c3 - -(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) -y₁-y₀ = a31*z₁ + a32*z₂ + γ*z₃ - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₃ -+ (6θ*(1-θ)/dt)*(a32*z₂) - -(1 + (-4θ + 3θ^2) + a31*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a32 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -# Predict z8 from z7 and z1 -θ = 1/c7 -dt = c7 - -(1 + (-4θ + 3θ^2))*z₁ + (-2θ + 3θ^2)*z₃ + (6θ*(1-θ)/dt)*(y₁-y₀) -y₁-y₀ = a71*z₁ + a72*z₂ + a73*z₃ + a74*z₄ + a75*z₅ + a76*z₆ + γ*z₇ - -(1 + (-4θ + 3θ^2) + a71*(6θ*(1-θ)/dt))*z₁ + -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt))*z₇ -+ (6θ*(1-θ)/dt)*(a72*z₂ + a73*z₃ + a74*z₄ + a75*z₅ + a76*z₆) - -(1 + (-4θ + 3θ^2) + a71*(6θ*(1-θ)/dt)) -(6θ*(1-θ)/dt)*a72 -(6θ*(1-θ)/dt)*a73 -(6θ*(1-θ)/dt)*a74 -(6θ*(1-θ)/dt)*a75 -(6θ*(1-θ)/dt)*a76 -(-2θ + 3θ^2 + γ*(6θ*(1-θ)/dt)) - -=# - -function KenCarp58Tableau(T, T2) - γ = convert(T2, 2 // 9) - a31 = convert(T, 2366667076620 // 8822750406821) - a32 = a31 - a41 = -convert(T, 257962897183 // 4451812247028) - a42 = a41 - a43 = convert(T, 128530224461 // 14379561246022) - a51 = -convert(T, 486229321650 // 11227943450093) - a52 = a51 - a53 = -convert(T, 225633144460 // 6633558740617) - a54 = convert(T, 1741320951451 // 6824444397158) - a61 = convert(T, 621307788657 // 4714163060173) - a62 = a61 - a63 = -convert(T, 125196015625 // 3866852212004) - a64 = convert(T, 940440206406 // 7593089888465) - a65 = convert(T, 961109811699 // 6734810228204) - a71 = convert(T, 2036305566805 // 6583108094622) - a72 = a71 - a73 = -convert(T, 3039402635899 // 4450598839912) - a74 = -convert(T, 1829510709469 // 31102090912115) - a75 = -convert(T, 286320471013 // 6931253422520) - a76 = convert(T, 8651533662697 // 9642993110008) - a83 = convert(T, 3517720773327 // 20256071687669) - a84 = convert(T, 4569610470461 // 17934693873752) - a85 = convert(T, 2819471173109 // 11655438449929) - a86 = convert(T, 3296210113763 // 10722700128969) - a87 = -convert(T, 1142099968913 // 5710983926999) - - # bhat3 = convert(T,520639020421//8300446712847) - # bhat4 = convert(T,4550235134915//17827758688493) - # bhat5 = convert(T,1482366381361//6201654941325) - # bhat6 = convert(T,5551607622171//13911031047899) - # bhat7 = -convert(T,5266607656330//36788968843917) - # bhat8 = convert(T,1074053359553//5740751784926) - - btilde3 = -convert(T, 18652552508630163520943320 // 168134443655105334713783643) # bhat3-a83 - btilde4 = convert(T, 141161430501477620145807 // 319735394533244397237135736) # bhat4-a84 - btilde5 = -convert(T, 207757214437709595456056 // 72283007456311581445415925) # bhat5-a85 - btilde6 = convert(T, 13674542533282477231637762 // 149163814411398370516486131) # bhat6-a86 - btilde7 = convert(T, 11939168497868428048898551 // 210101209758476969753215083) # bhat7-a87 - btilde8 = -convert(T, 1815023333875 // 51666766064334) # bhat8-γ - #c2 = 2γ - c3 = convert(T2, 6456083330201 // 8509243623797) - c4 = convert(T2, 1632083962415 // 14158861528103) - c5 = convert(T2, 6365430648612 // 17842476412687) - c6 = convert(T2, 18 // 25) - c7 = convert(T2, 191 // 200) - - α31 = -convert(T2, 796131459065721 // 1125899906842624) - α32 = convert(T2, 961015682954173 // 562949953421312) - α41 = convert(T2, 3335563016633385 // 4503599627370496) - α42 = convert(T2, 2336073221474223 // 9007199254740992) - α51 = convert(T2, 1777088537295433 // 9007199254740992) - α52 = convert(T2, 7230110717445555 // 9007199254740992) - α61 = convert(T2, 305461594360167 // 36028797018963968) - α62 = convert(T2, 3700851199347703 // 36028797018963968) - α63 = convert(T2, 8005621056314023 // 9007199254740992) - α71 = convert(T2, 247009276011491 // 9007199254740992) - α72 = -convert(T2, 6222030107065861 // 9007199254740992) - α73 = convert(T2, 1872777510724421 // 1125899906842624) - α81 = convert(T2, 180631849429283 // 36028797018963968) - α82 = -convert(T2, 3454740038041085 // 36028797018963968) - α83 = convert(T2, 476708848972457 // 2251799813685248) - α84 = convert(T2, 5255799236757313 // 288230376151711744) - α85 = convert(T2, 3690914796734375 // 288230376151711744) - α86 = -convert(T2, 5010195363762467 // 18014398509481984) - α87 = convert(T2, 5072201887169367 // 4503599627370496) - - ea21 = convert(T, 4 // 9) - ea31 = convert(T, 1 // 9) - ea32 = convert(T, 1183333538310 // 1827251437969) - ea41 = convert(T, 895379019517 // 9750411845327) - ea42 = convert(T, 477606656805 // 13473228687314) - ea43 = -convert(T, 112564739183 // 9373365219272) - ea51 = -convert(T, 4458043123994 // 13015289567637) - ea52 = -convert(T, 2500665203865 // 9342069639922) - ea53 = convert(T, 983347055801 // 8893519644487) - ea54 = convert(T, 2185051477207 // 2551468980502) - ea61 = -convert(T, 167316361917 // 17121522574472) - ea62 = convert(T, 1605541814917 // 7619724128744) - ea63 = convert(T, 991021770328 // 13052792161721) - ea64 = convert(T, 2342280609577 // 11279663441611) - ea65 = convert(T, 3012424348531 // 12792462456678) - ea71 = convert(T, 6680998715867 // 14310383562358) - ea72 = convert(T, 5029118570809 // 3897454228471) - ea73 = convert(T, 2415062538259 // 6382199904604) - ea74 = -convert(T, 3924368632305 // 6964820224454) - ea75 = -convert(T, 4331110370267 // 15021686902756) - ea76 = -convert(T, 3944303808049 // 11994238218192) - ea81 = convert(T, 2193717860234 // 3570523412979) - ea82 = convert(T, 2193717860234 // 3570523412979) - ea83 = convert(T, 5952760925747 // 18750164281544) - ea84 = -convert(T, 4412967128996 // 6196664114337) - ea85 = convert(T, 4151782504231 // 36106512998704) - ea86 = convert(T, 572599549169 // 6265429158920) - ea87 = -convert(T, 457874356192 // 11306498036315) - - eb3 = convert(T, 3517720773327 // 20256071687669) - eb4 = convert(T, 4569610470461 // 17934693873752) - eb5 = convert(T, 2819471173109 // 11655438449929) - eb6 = convert(T, 3296210113763 // 10722700128969) - eb7 = -convert(T, 1142099968913 // 5710983926999) - eb8 = convert(T, 2 // 9) - - ebtilde3 = -convert(T, 18652552508630163520943320 // 168134443655105334713783643)#bhat3-eb3 - ebtilde4 = convert(T, 141161430501477620145807 // 319735394533244397237135736) #bhat4-eb4 - ebtilde5 = -convert(T, 207757214437709595456056 // 72283007456311581445415925) #bhat5-eb5 - ebtilde6 = convert(T, 13674542533282477231637762 // 149163814411398370516486131) #bhat6-eb6 - ebtilde7 = convert(T, 11939168497868428048898551 // 210101209758476969753215083) #bhat7-eb7 - ebtilde8 = -convert(T, 1815023333875 // 51666766064334) #bhat8-eb8 - - KenCarp58Tableau(γ, a31, a32, a41, a42, a43, a51, a52, a53, a54, a61, a62, a63, a64, - a65, - a71, a72, a73, a74, a75, a76, a83, a84, a85, a86, a87, - c3, c4, c5, c6, c7, α31, α32, α41, α42, α51, α52, - α61, α62, α63, α71, α72, α73, α81, α82, α83, α84, α85, α86, α87, - btilde3, btilde4, btilde5, btilde6, btilde7, btilde8, - ea21, ea31, ea32, ea41, ea42, ea43, ea51, ea52, ea53, ea54, ea61, ea62, - ea63, - ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, - ea85, ea86, ea87, eb3, eb4, eb5, eb6, eb7, eb8, ebtilde3, - ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8) -end \ No newline at end of file From e32dd5a842581f778530038d0f8f4c7e3544548e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 23:25:40 +0530 Subject: [PATCH 026/112] Added SDIRK solvers --- lib/OrdinaryDiffEqSDIRK/Project.toml | 19 + .../src/OrdinaryDiffEqSDIRK.jl | 18 + lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl | 0 lib/OrdinaryDiffEqSDIRK/src/algorithms.jl | 862 +++++++++++++++++ .../src}/kencarp_kvaerno_caches.jl | 2 +- .../src}/kencarp_kvaerno_perform_step.jl | 2 +- .../OrdinaryDiffEqSDIRK/src}/sdirk_caches.jl | 2 +- .../src}/sdirk_perform_step.jl | 2 +- .../src}/sdirk_tableaus.jl | 2 +- src/OrdinaryDiffEq.jl | 20 +- src/algorithms.jl | 863 ------------------ test/runtests.jl | 6 + 12 files changed, 919 insertions(+), 879 deletions(-) create mode 100644 lib/OrdinaryDiffEqSDIRK/Project.toml create mode 100644 lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl create mode 100644 lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqSDIRK/src/algorithms.jl rename {src/caches => lib/OrdinaryDiffEqSDIRK/src}/kencarp_kvaerno_caches.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqSDIRK/src}/kencarp_kvaerno_perform_step.jl (99%) rename {src/caches => lib/OrdinaryDiffEqSDIRK/src}/sdirk_caches.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqSDIRK/src}/sdirk_perform_step.jl (99%) rename {src/tableaus => lib/OrdinaryDiffEqSDIRK/src}/sdirk_tableaus.jl (99%) diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml new file mode 100644 index 0000000000..db13e6df07 --- /dev/null +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -0,0 +1,19 @@ +name = "OrdinaryDiffEqSDIRK" +uuid = "2d112036-d095-4a1e-ab9a-08536f3ecdbf" +authors = ["ParamThakkar123 "] +version = "1.0.0" + +[deps] +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" + +[compat] +julia = "1.10" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl new file mode 100644 index 0000000000..328901df20 --- /dev/null +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -0,0 +1,18 @@ +module OrdinaryDiffEqSDIRK + +include("algorithms.jl") +include("alg_utils.jl") +include("sdirk_caches.jl") +include("kencarp_kvaerno_caches.jl") +include("sdirk_perform_step.jl") +include("kencarp_kvaerno_perform_step.jl") +include("sdirk_tableaus.jl") + +export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, + Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, + Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, + SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, + SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA + +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl new file mode 100644 index 0000000000..2cb31058e5 --- /dev/null +++ b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl @@ -0,0 +1,862 @@ +# SDIRK Methods +""" +ImplicitEuler: SDIRK Method +A 1st order implicit solver. A-B-L-stable. Adaptive timestepping through a divided differences estimate via memory. +Strong-stability preserving (SSP). +""" +struct ImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function ImplicitEuler(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant, + controller = :PI, step_limiter! = trivial_limiter!) + ImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, precs, extrapolant, controller, step_limiter!) +end +""" +ImplicitMidpoint: SDIRK Method +A second order A-stable symplectic and symmetric implicit solver. +Good for highly stiff equations which need symplectic integration. +""" +struct ImplicitMidpoint{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + step_limiter!::StepLimiter +end + +function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, step_limiter! = trivial_limiter!) + ImplicitMidpoint{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + step_limiter!) +end + +""" +Andre Vladimirescu. 1994. The Spice Book. John Wiley & Sons, Inc., New York, +NY, USA. + +Trapezoid: SDIRK Method +A second order A-stable symmetric ESDIRK method. +"Almost symplectic" without numerical dampening. +Also known as Crank-Nicolson when applied to PDEs. Adaptive timestepping via divided +differences approximation to the second derivative terms in the local truncation error +estimate (the SPICE approximation strategy). +""" +struct Trapezoid{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function Trapezoid(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + controller, + step_limiter!) +end + +""" +@article{hosea1996analysis, +title={Analysis and implementation of TR-BDF2}, +author={Hosea, ME and Shampine, LF}, +journal={Applied Numerical Mathematics}, +volume={20}, +number={1-2}, +pages={21--37}, +year={1996}, +publisher={Elsevier} +} + +TRBDF2: SDIRK Method +A second order A-B-L-S-stable one-step ESDIRK method. +Includes stiffness-robust error estimates for accurate adaptive timestepping, smoothed derivatives for highly stiff and oscillatory problems. +""" +struct TRBDF2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function TRBDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + TRBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace TRBDF2 + +""" +@article{hindmarsh2005sundials, +title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, +author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, +journal={ACM Transactions on Mathematical Software (TOMS)}, +volume={31}, +number={3}, +pages={363--396}, +year={2005}, +publisher={ACM} +} + +SDIRK2: SDIRK Method +An A-B-L stable 2nd order SDIRK method +""" +struct SDIRK2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function SDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + SDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}( + linsolve, nlsolve, precs, smooth_est, extrapolant, + controller, + step_limiter!) +end + +struct SDIRK22{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function SDIRK22(; + chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + controller, + step_limiter!) +end + +struct SSPSDIRK2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} # Not adaptive + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end + +function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :constant, + controller = :PI) + SSPSDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno3: SDIRK Method +An A-L stable stiffly-accurate 3rd order ESDIRK method +""" +struct Kvaerno3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp3: SDIRK Method +An A-L stable stiffly-accurate 3rd order ESDIRK method with splitting +""" +struct KenCarp3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +struct CFNLIRK3{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function CFNLIRK3(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + CFNLIRK3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +""" +@article{hindmarsh2005sundials, +title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, +author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, +journal={ACM Transactions on Mathematical Software (TOMS)}, +volume={31}, +number={3}, +pages={363--396}, +year={2005}, +publisher={ACM} +} + +Cash4: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Cash4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + embedding::Int + controller::Symbol +end +function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, embedding = 3) + Cash4{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( + linsolve, + nlsolve, + precs, + smooth_est, + extrapolant, + embedding, + controller) +end + +struct SFSDIRK4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function SFSDIRK4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK5{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK6{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK6(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK6{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK7{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK7(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK7{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +struct SFSDIRK8{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end + +function SFSDIRK8(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear) + SFSDIRK8{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +""" +E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and +differential-algebraic problems. Computational mathematics (2nd revised ed.), +Springer (1996) + +Hairer4: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Hairer4{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function Hairer4(; + chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + Hairer4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and +differential-algebraic problems. Computational mathematics (2nd revised ed.), +Springer (1996) + +Hairer42: SDIRK Method +An A-L stable 4th order SDIRK method +""" +struct Hairer42{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function Hairer42(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + Hairer42{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno4: SDIRK Method +An A-L stable stiffly-accurate 4th order ESDIRK method. +""" +struct Kvaerno4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@article{kvaerno2004singly, +title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, +author={Kv{\\ae}rn{\\o}, Anne}, +journal={BIT Numerical Mathematics}, +volume={44}, +number={3}, +pages={489--502}, +year={2004}, +publisher={Springer} +} + +Kvaerno5: SDIRK Method +An A-L stable stiffly-accurate 5th order ESDIRK method +""" +struct Kvaerno5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function Kvaerno5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + Kvaerno5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp4: SDIRK Method +An A-L stable stiffly-accurate 4th order ESDIRK method with splitting +""" +struct KenCarp4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp4(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace KenCarp4 + +""" +@article{kennedy2019higher, +title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, +author={Kennedy, Christopher A and Carpenter, Mark H}, +journal={Applied Numerical Mathematics}, +volume={136}, +pages={183--205}, +year={2019}, +publisher={Elsevier} +} + +KenCarp47: SDIRK Method +An A-L stable stiffly-accurate 4th order seven-stage ESDIRK method with splitting +""" +struct KenCarp47{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function KenCarp47(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + KenCarp47{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +""" +@book{kennedy2001additive, +title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, +author={Kennedy, Christopher Alan}, +year={2001}, +publisher={National Aeronautics and Space Administration, Langley Research Center} +} + +KenCarp5: SDIRK Method +An A-L stable stiffly-accurate 5th order ESDIRK method with splitting +""" +struct KenCarp5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function KenCarp5(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI, step_limiter! = trivial_limiter!) + KenCarp5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, + smooth_est, extrapolant, controller, step_limiter!) +end +""" +@article{kennedy2019higher, +title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, +author={Kennedy, Christopher A and Carpenter, Mark H}, +journal={Applied Numerical Mathematics}, +volume={136}, +pages={183--205}, +year={2019}, +publisher={Elsevier} +} + +KenCarp58: SDIRK Method +An A-L stable stiffly-accurate 5th order eight-stage ESDIRK method with splitting +""" +struct KenCarp58{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + smooth_est::Bool + extrapolant::Symbol + controller::Symbol +end +function KenCarp58(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :PI) + KenCarp58{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, + controller) +end + +# `smooth_est` is not necessary, as the embedded method is also L-stable +struct ESDIRK54I8L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK54I8L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK436L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK436L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK437L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK437L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} +} +""" +struct ESDIRK547L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK547L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end + +""" +@article{Kennedy2019DiagonallyIR, +title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, +author={Christopher A. Kennedy and Mark H. Carpenter}, +journal={Applied Numerical Mathematics}, +year={2019}, +volume={146}, +pages={221-244} + +Currently has STABILITY ISSUES, causing it to fail the adaptive tests. +Check issue https://github.com/SciML/OrdinaryDiffEq.jl/issues/1933 for more details. +} +""" +struct ESDIRK659L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + controller::Symbol +end +function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, controller = :PI) + ESDIRK659L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, + controller) +end \ No newline at end of file diff --git a/src/caches/kencarp_kvaerno_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl similarity index 99% rename from src/caches/kencarp_kvaerno_caches.jl rename to lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl index e239a42f10..0af6130b8b 100644 --- a/src/caches/kencarp_kvaerno_caches.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl @@ -639,4 +639,4 @@ function alg_cache(alg::KenCarp58, u, rate_prototype, ::Type{uEltypeNoUnits}, KenCarp58Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, k1, k2, k3, k4, k5, k6, k7, k8, atmp, nlsolver, tab) -end +end \ No newline at end of file diff --git a/src/perform_step/kencarp_kvaerno_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl similarity index 99% rename from src/perform_step/kencarp_kvaerno_perform_step.jl rename to lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl index 1b3d6f1a7b..bd43f4faea 100644 --- a/src/perform_step/kencarp_kvaerno_perform_step.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl @@ -2662,4 +2662,4 @@ end else @.. broadcast=false integrator.fsallast=z₈ / dt end -end +end \ No newline at end of file diff --git a/src/caches/sdirk_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl similarity index 99% rename from src/caches/sdirk_caches.jl rename to lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl index 5664341626..eafca44bd1 100644 --- a/src/caches/sdirk_caches.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl @@ -995,4 +995,4 @@ function alg_cache(alg::ESDIRK659L2SA, u, rate_prototype, ::Type{uEltypeNoUnits} nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) ESDIRK659L2SAConstantCache(nlsolver, tab) -end +end \ No newline at end of file diff --git a/src/perform_step/sdirk_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl similarity index 99% rename from src/perform_step/sdirk_perform_step.jl rename to lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl index d94bf0085f..84db426936 100644 --- a/src/perform_step/sdirk_perform_step.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl @@ -3151,4 +3151,4 @@ end @.. broadcast=false integrator.fsallast=z₉ / dt return -end +end \ No newline at end of file diff --git a/src/tableaus/sdirk_tableaus.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl similarity index 99% rename from src/tableaus/sdirk_tableaus.jl rename to lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl index ed95cef957..f008557fda 100644 --- a/src/tableaus/sdirk_tableaus.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl @@ -2773,4 +2773,4 @@ function KenCarp58Tableau(T, T2) ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, ea85, ea86, ea87, eb3, eb4, eb5, eb6, eb7, eb8, ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8) -end +end \ No newline at end of file diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 8eabc4c6ee..308a0e992a 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -149,9 +149,7 @@ include("generic_rosenbrock.jl") include("caches/basic_caches.jl") include("caches/low_order_rk_caches.jl") include("caches/high_order_rk_caches.jl") -include("caches/sdirk_caches.jl") include("caches/firk_caches.jl") -include("caches/kencarp_kvaerno_caches.jl") include("caches/linear_caches.jl") include("caches/linear_nonlinear_caches.jl") include("caches/rosenbrock_caches.jl") @@ -166,7 +164,6 @@ include("caches/qprk_caches.jl") include("tableaus/low_order_rk_tableaus.jl") include("tableaus/high_order_rk_tableaus.jl") include("tableaus/rosenbrock_tableaus.jl") -include("tableaus/sdirk_tableaus.jl") include("tableaus/firk_tableaus.jl") include("tableaus/qprk_tableaus.jl") @@ -186,7 +183,6 @@ include("perform_step/exponential_rk_perform_step.jl") include("perform_step/explicit_rk_perform_step.jl") include("perform_step/low_order_rk_perform_step.jl") include("perform_step/high_order_rk_perform_step.jl") -include("perform_step/sdirk_perform_step.jl") include("perform_step/kencarp_kvaerno_perform_step.jl") include("perform_step/firk_perform_step.jl") include("perform_step/rosenbrock_perform_step.jl") @@ -279,6 +275,15 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm +include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") +using ..OrdinaryDiffEqSDIRK +export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, + Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, + Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, + SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, + SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA + import PrecompileTools PrecompileTools.@compile_workload begin @@ -417,13 +422,6 @@ export FunctionMap, Euler, Heun, Ralston, Midpoint, RK4, ExplicitRK, OwrenZen3, export RadauIIA3, RadauIIA5 -export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, - Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, - Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, - SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, - SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, - SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA - export MagnusMidpoint, LinearExponential, MagnusLeapfrog, LieEuler, CayleyEuler, MagnusGauss4, MagnusNC6, MagnusGL6, MagnusGL8, MagnusNC8, MagnusGL4, MagnusAdapt4, RKMK2, RKMK4, LieRK4, CG2, CG3, CG4a diff --git a/src/algorithms.jl b/src/algorithms.jl index 7b7ae3ce6e..c7ba3ce4d9 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -997,869 +997,6 @@ TruncatedStacktraces.@truncate_stacktrace RadauIIA5 ################################################################################ -# SDIRK Methods -""" -ImplicitEuler: SDIRK Method -A 1st order implicit solver. A-B-L-stable. Adaptive timestepping through a divided differences estimate via memory. -Strong-stability preserving (SSP). -""" -struct ImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function ImplicitEuler(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant, - controller = :PI, step_limiter! = trivial_limiter!) - ImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, precs, extrapolant, controller, step_limiter!) -end -""" -ImplicitMidpoint: SDIRK Method -A second order A-stable symplectic and symmetric implicit solver. -Good for highly stiff equations which need symplectic integration. -""" -struct ImplicitMidpoint{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - step_limiter!::StepLimiter -end - -function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, step_limiter! = trivial_limiter!) - ImplicitMidpoint{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - step_limiter!) -end - -""" -Andre Vladimirescu. 1994. The Spice Book. John Wiley & Sons, Inc., New York, -NY, USA. - -Trapezoid: SDIRK Method -A second order A-stable symmetric ESDIRK method. -"Almost symplectic" without numerical dampening. -Also known as Crank-Nicolson when applied to PDEs. Adaptive timestepping via divided -differences approximation to the second derivative terms in the local truncation error -estimate (the SPICE approximation strategy). -""" -struct Trapezoid{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function Trapezoid(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - controller, - step_limiter!) -end - -""" -@article{hosea1996analysis, -title={Analysis and implementation of TR-BDF2}, -author={Hosea, ME and Shampine, LF}, -journal={Applied Numerical Mathematics}, -volume={20}, -number={1-2}, -pages={21--37}, -year={1996}, -publisher={Elsevier} -} - -TRBDF2: SDIRK Method -A second order A-B-L-S-stable one-step ESDIRK method. -Includes stiffness-robust error estimates for accurate adaptive timestepping, smoothed derivatives for highly stiff and oscillatory problems. -""" -struct TRBDF2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function TRBDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - TRBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace TRBDF2 - -""" -@article{hindmarsh2005sundials, -title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, -author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, -journal={ACM Transactions on Mathematical Software (TOMS)}, -volume={31}, -number={3}, -pages={363--396}, -year={2005}, -publisher={ACM} -} - -SDIRK2: SDIRK Method -An A-B-L stable 2nd order SDIRK method -""" -struct SDIRK2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function SDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - SDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}( - linsolve, nlsolve, precs, smooth_est, extrapolant, - controller, - step_limiter!) -end - -struct SDIRK22{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function SDIRK22(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Trapezoid{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - controller, - step_limiter!) -end - -struct SSPSDIRK2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} # Not adaptive - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end - -function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :constant, - controller = :PI) - SSPSDIRK2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno3: SDIRK Method -An A-L stable stiffly-accurate 3rd order ESDIRK method -""" -struct Kvaerno3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp3: SDIRK Method -An A-L stable stiffly-accurate 3rd order ESDIRK method with splitting -""" -struct KenCarp3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -struct CFNLIRK3{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function CFNLIRK3(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - CFNLIRK3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -""" -@article{hindmarsh2005sundials, -title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, -author={Hindmarsh, Alan C and Brown, Peter N and Grant, Keith E and Lee, Steven L and Serban, Radu and Shumaker, Dan E and Woodward, Carol S}, -journal={ACM Transactions on Mathematical Software (TOMS)}, -volume={31}, -number={3}, -pages={363--396}, -year={2005}, -publisher={ACM} -} - -Cash4: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Cash4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - embedding::Int - controller::Symbol -end -function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, embedding = 3) - Cash4{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( - linsolve, - nlsolve, - precs, - smooth_est, - extrapolant, - embedding, - controller) -end - -struct SFSDIRK4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function SFSDIRK4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK5{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK6{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK6(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK6{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK7{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK7(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK7{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -struct SFSDIRK8{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end - -function SFSDIRK8(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear) - SFSDIRK8{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end - -""" -E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and -differential-algebraic problems. Computational mathematics (2nd revised ed.), -Springer (1996) - -Hairer4: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Hairer4{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function Hairer4(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - Hairer4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -E. Hairer, G. Wanner, Solving ordinary differential equations II, stiff and -differential-algebraic problems. Computational mathematics (2nd revised ed.), -Springer (1996) - -Hairer42: SDIRK Method -An A-L stable 4th order SDIRK method -""" -struct Hairer42{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function Hairer42(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - Hairer42{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno4: SDIRK Method -An A-L stable stiffly-accurate 4th order ESDIRK method. -""" -struct Kvaerno4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@article{kvaerno2004singly, -title={Singly diagonally implicit Runge--Kutta methods with an explicit first stage}, -author={Kv{\\ae}rn{\\o}, Anne}, -journal={BIT Numerical Mathematics}, -volume={44}, -number={3}, -pages={489--502}, -year={2004}, -publisher={Springer} -} - -Kvaerno5: SDIRK Method -An A-L stable stiffly-accurate 5th order ESDIRK method -""" -struct Kvaerno5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function Kvaerno5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - Kvaerno5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp4: SDIRK Method -An A-L stable stiffly-accurate 4th order ESDIRK method with splitting -""" -struct KenCarp4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp4(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace KenCarp4 - -""" -@article{kennedy2019higher, -title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, -author={Kennedy, Christopher A and Carpenter, Mark H}, -journal={Applied Numerical Mathematics}, -volume={136}, -pages={183--205}, -year={2019}, -publisher={Elsevier} -} - -KenCarp47: SDIRK Method -An A-L stable stiffly-accurate 4th order seven-stage ESDIRK method with splitting -""" -struct KenCarp47{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function KenCarp47(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - KenCarp47{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -""" -@book{kennedy2001additive, -title={Additive Runge-Kutta schemes for convection-diffusion-reaction equations}, -author={Kennedy, Christopher Alan}, -year={2001}, -publisher={National Aeronautics and Space Administration, Langley Research Center} -} - -KenCarp5: SDIRK Method -An A-L stable stiffly-accurate 5th order ESDIRK method with splitting -""" -struct KenCarp5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function KenCarp5(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI, step_limiter! = trivial_limiter!) - KenCarp5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, - smooth_est, extrapolant, controller, step_limiter!) -end -""" -@article{kennedy2019higher, -title={Higher-order additive Runge--Kutta schemes for ordinary differential equations}, -author={Kennedy, Christopher A and Carpenter, Mark H}, -journal={Applied Numerical Mathematics}, -volume={136}, -pages={183--205}, -year={2019}, -publisher={Elsevier} -} - -KenCarp58: SDIRK Method -An A-L stable stiffly-accurate 5th order eight-stage ESDIRK method with splitting -""" -struct KenCarp58{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - smooth_est::Bool - extrapolant::Symbol - controller::Symbol -end -function KenCarp58(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :PI) - KenCarp58{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) -end - -# `smooth_est` is not necessary, as the embedded method is also L-stable -struct ESDIRK54I8L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK54I8L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK436L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK436L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK437L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK437L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} -} -""" -struct ESDIRK547L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK547L2SA2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - -""" -@article{Kennedy2019DiagonallyIR, -title={Diagonally implicit Runge–Kutta methods for stiff ODEs}, -author={Christopher A. Kennedy and Mark H. Carpenter}, -journal={Applied Numerical Mathematics}, -year={2019}, -volume={146}, -pages={221-244} - -Currently has STABILITY ISSUES, causing it to fail the adaptive tests. -Check issue https://github.com/SciML/OrdinaryDiffEq.jl/issues/1933 for more details. -} -""" -struct ESDIRK659L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - controller::Symbol -end -function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, controller = :PI) - ESDIRK659L2SA{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) -end - ################################################################################ # Rosenbrock Methods diff --git a/test/runtests.jl b/test/runtests.jl index 1dbd745f77..2bce643dd9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -71,6 +71,12 @@ function activate_symplectic_rk() Pkg.instantiate() end +function activate_sdirk() + Pkg.activate("../lib/OrdinaryDiffEqSDIRK") + Pkg.develop(PackageSpec(path = dirname(@__DIR__))) + Pkg.instantiate() +end + #Start Test Script @time begin From 753ad6d54b463e780eca9660ceaa2b5373704efe Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 23:39:04 +0530 Subject: [PATCH 027/112] Fixes --- lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl | 48 ++++++++++++++++++++++++ src/alg_utils.jl | 43 --------------------- src/algorithms.jl | 4 +- 3 files changed, 50 insertions(+), 45 deletions(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl index e69de29bb2..50684fb185 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl @@ -0,0 +1,48 @@ +alg_extrapolates(alg::ImplicitEuler) = true +alg_extrapolates(alg::Trapezoid) = true +alg_extrapolates(alg::SDIRK22) = true + +alg_order(alg::Trapezoid) = 2 +alg_order(alg::ImplicitEuler) = 1 +alg_order(alg::ImplicitMidpoint) = 2 +alg_order(alg::TRBDF2) = 2 +alg_order(alg::SSPSDIRK2) = 2 +alg_order(alg::SDIRK2) = 2 +alg_order(alg::SDIRK22) = 2 +alg_order(alg::Kvaerno3) = 3 +alg_order(alg::Kvaerno4) = 4 +alg_order(alg::Kvaerno5) = 5 +alg_order(alg::ESDIRK54I8L2SA) = 5 +alg_order(alg::ESDIRK436L2SA2) = 4 +alg_order(alg::ESDIRK437L2SA) = 4 +alg_order(alg::ESDIRK547L2SA2) = 5 +alg_order(alg::ESDIRK659L2SA) = 6 +alg_order(alg::KenCarp3) = 3 +alg_order(alg::CFNLIRK3) = 3 +alg_order(alg::KenCarp4) = 4 +alg_order(alg::KenCarp47) = 4 +alg_order(alg::KenCarp5) = 5 +alg_order(alg::KenCarp58) = 5 +alg_order(alg::Cash4) = 4 +alg_order(alg::SFSDIRK4) = 4 +alg_order(alg::SFSDIRK5) = 4 +alg_order(alg::SFSDIRK6) = 4 +alg_order(alg::SFSDIRK7) = 4 +alg_order(alg::SFSDIRK8) = 4 +alg_order(alg::Hairer4) = 4 +alg_order(alg::Hairer42) = 4 + +function isesdirk(alg::Union{KenCarp3, KenCarp4, KenCarp5, KenCarp58, + Kvaerno3, Kvaerno4, Kvaerno5, ESDIRK437L2SA, + ESDIRK54I8L2SA, ESDIRK436L2SA2, ESDIRK547L2SA2, + ESDIRK659L2SA, CFNLIRK3}) + true +end + +alg_adaptive_order(alg::Trapezoid) = 1 +alg_adaptive_order(alg::ImplicitMidpoint) = 1 +alg_adaptive_order(alg::ImplicitEuler) = 0 + +ssp_coefficient(alg::SSPSDIRK2) = 4 + +isesdirk(alg::TRBDF2) = true \ No newline at end of file diff --git a/src/alg_utils.jl b/src/alg_utils.jl index da79af736d..5cc5d7644e 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -347,11 +347,8 @@ end alg_extrapolates(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_extrapolates(alg::CompositeAlgorithm) = any(alg_extrapolates.(alg.algs)) -alg_extrapolates(alg::ImplicitEuler) = true alg_extrapolates(alg::DImplicitEuler) = true alg_extrapolates(alg::DABDF2) = true -alg_extrapolates(alg::Trapezoid) = true -alg_extrapolates(alg::SDIRK22) = true alg_extrapolates(alg::ABDF2) = true alg_extrapolates(alg::SBDF) = true alg_extrapolates(alg::MEBDF2) = true @@ -441,7 +438,6 @@ alg_order(alg::TanYam7) = 7 alg_order(alg::TsitPap8) = 8 alg_order(alg::RadauIIA3) = 3 alg_order(alg::RadauIIA5) = 5 -alg_order(alg::ImplicitEuler) = 1 alg_order(alg::RKMK2) = 2 alg_order(alg::RKMK4) = 4 alg_order(alg::LieRK4) = 4 @@ -458,34 +454,6 @@ alg_order(alg::MagnusGL4) = 4 alg_order(alg::MagnusAdapt4) = 4 alg_order(alg::LinearExponential) = 1 alg_order(alg::MagnusLeapfrog) = 2 -alg_order(alg::Trapezoid) = 2 -alg_order(alg::ImplicitMidpoint) = 2 -alg_order(alg::TRBDF2) = 2 -alg_order(alg::SSPSDIRK2) = 2 -alg_order(alg::SDIRK2) = 2 -alg_order(alg::SDIRK22) = 2 -alg_order(alg::Kvaerno3) = 3 -alg_order(alg::Kvaerno4) = 4 -alg_order(alg::Kvaerno5) = 5 -alg_order(alg::ESDIRK54I8L2SA) = 5 -alg_order(alg::ESDIRK436L2SA2) = 4 -alg_order(alg::ESDIRK437L2SA) = 4 -alg_order(alg::ESDIRK547L2SA2) = 5 -alg_order(alg::ESDIRK659L2SA) = 6 -alg_order(alg::KenCarp3) = 3 -alg_order(alg::CFNLIRK3) = 3 -alg_order(alg::KenCarp4) = 4 -alg_order(alg::KenCarp47) = 4 -alg_order(alg::KenCarp5) = 5 -alg_order(alg::KenCarp58) = 5 -alg_order(alg::Cash4) = 4 -alg_order(alg::SFSDIRK4) = 4 -alg_order(alg::SFSDIRK5) = 4 -alg_order(alg::SFSDIRK6) = 4 -alg_order(alg::SFSDIRK7) = 4 -alg_order(alg::SFSDIRK8) = 4 -alg_order(alg::Hairer4) = 4 -alg_order(alg::Hairer42) = 4 alg_order(alg::PFRK87) = 8 alg_order(alg::ROS2) = 2 @@ -580,11 +548,8 @@ alg_adaptive_order(alg::Rosenbrock32) = 2 alg_adaptive_order(alg::RadauIIA3) = 1 alg_adaptive_order(alg::RadauIIA5) = 3 -alg_adaptive_order(alg::ImplicitEuler) = 0 -alg_adaptive_order(alg::Trapezoid) = 1 # this is actually incorrect and is purposefully decreased as this tends # to track the real error much better -alg_adaptive_order(alg::ImplicitMidpoint) = 1 # this is actually incorrect and is purposefully decreased as this tends # to track the real error much better @@ -669,7 +634,6 @@ ssp_coefficient(alg::Euler) = 1 # We shouldn't do this probably. #ssp_coefficient(alg::ImplicitEuler) = Inf -ssp_coefficient(alg::SSPSDIRK2) = 4 # stability regions alg_stability_size(alg::ExplicitRK) = alg.tableau.stability_size @@ -750,13 +714,6 @@ isWmethod(alg::ROS34PRw) = true isWmethod(alg::ROK4a) = true isWmethod(alg::RosenbrockW6S4OS) = true -isesdirk(alg::TRBDF2) = true -function isesdirk(alg::Union{KenCarp3, KenCarp4, KenCarp5, KenCarp58, - Kvaerno3, Kvaerno4, Kvaerno5, ESDIRK437L2SA, - ESDIRK54I8L2SA, ESDIRK436L2SA2, ESDIRK547L2SA2, - ESDIRK659L2SA, CFNLIRK3}) - true -end isesdirk(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false diff --git a/src/algorithms.jl b/src/algorithms.jl index c7ba3ce4d9..d5994e4eba 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -1430,8 +1430,8 @@ const MultistepAlgorithms = Union{ ABDF2, AB3, AB4, AB5, ABM32, ABM43, ABM54} -const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF, - KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, CFNLIRK3} +#KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, CFNLIRK3 +const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF} #= struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} From 925abf348a76b84d990943b92c1e691df79ae58e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 23:42:38 +0530 Subject: [PATCH 028/112] Fixes --- src/caches/bdf_caches.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/caches/bdf_caches.jl b/src/caches/bdf_caches.jl index 78a64c7c7b..fe33d2e7aa 100644 --- a/src/caches/bdf_caches.jl +++ b/src/caches/bdf_caches.jl @@ -1,3 +1,7 @@ +mutable struct ImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end + @cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: OrdinaryDiffEqConstantCache nlsolver::N From 7db2567687d7c59c2377ead658c0438b5e6effcf Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 23:50:31 +0530 Subject: [PATCH 029/112] fixes --- src/caches/bdf_caches.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/caches/bdf_caches.jl b/src/caches/bdf_caches.jl index fe33d2e7aa..ea4de9c61f 100644 --- a/src/caches/bdf_caches.jl +++ b/src/caches/bdf_caches.jl @@ -1,6 +1,4 @@ -mutable struct ImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end +using OrdinaryDiffEq: ImplicitEulerCache, ImplicitEulerConstantCache @cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: OrdinaryDiffEqConstantCache From 97b40068c6bfdc421fb6d17810bfe7feec7de253 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sun, 14 Jul 2024 23:54:52 +0530 Subject: [PATCH 030/112] Cache --- src/caches/bdf_caches.jl | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/caches/bdf_caches.jl b/src/caches/bdf_caches.jl index ea4de9c61f..89743a5852 100644 --- a/src/caches/bdf_caches.jl +++ b/src/caches/bdf_caches.jl @@ -1,4 +1,38 @@ -using OrdinaryDiffEq: ImplicitEulerCache, ImplicitEulerConstantCache +@cache mutable struct ImplicitEulerCache{ + uType, rateType, uNoUnitsType, N, AV, StepLimiter} <: + SDIRKMutableCache + u::uType + uprev::uType + uprev2::uType + fsalfirst::rateType + atmp::uNoUnitsType + nlsolver::N + algebraic_vars::AV + step_limiter!::StepLimiter +end + +function alg_cache(alg::ImplicitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, + ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, + ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + γ, c = 1, 1 + nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, + uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) + fsalfirst = zero(rate_prototype) + + atmp = similar(u, uEltypeNoUnits) + recursivefill!(atmp, false) + + algebraic_vars = f.mass_matrix === I ? nothing : + [all(iszero, x) for x in eachcol(f.mass_matrix)] + + ImplicitEulerCache( + u, uprev, uprev2, fsalfirst, atmp, nlsolver, algebraic_vars, alg.step_limiter!) +end + +mutable struct ImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache + nlsolver::N +end @cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: OrdinaryDiffEqConstantCache From 5e3d95da663a6fb39e6be2e5d49dbd040c0c09e3 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Mon, 15 Jul 2024 00:02:18 +0530 Subject: [PATCH 031/112] Cache --- src/OrdinaryDiffEq.jl | 4 ++-- src/caches/bdf_caches.jl | 36 ------------------------------------ 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 308a0e992a..2d5288099d 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -155,7 +155,6 @@ include("caches/linear_nonlinear_caches.jl") include("caches/rosenbrock_caches.jl") include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") -include("caches/bdf_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") include("caches/dae_caches.jl") @@ -183,7 +182,6 @@ include("perform_step/exponential_rk_perform_step.jl") include("perform_step/explicit_rk_perform_step.jl") include("perform_step/low_order_rk_perform_step.jl") include("perform_step/high_order_rk_perform_step.jl") -include("perform_step/kencarp_kvaerno_perform_step.jl") include("perform_step/firk_perform_step.jl") include("perform_step/rosenbrock_perform_step.jl") include("perform_step/composite_perform_step.jl") @@ -284,6 +282,8 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA +include("caches/bdf_caches.jl") + import PrecompileTools PrecompileTools.@compile_workload begin diff --git a/src/caches/bdf_caches.jl b/src/caches/bdf_caches.jl index 89743a5852..78a64c7c7b 100644 --- a/src/caches/bdf_caches.jl +++ b/src/caches/bdf_caches.jl @@ -1,39 +1,3 @@ -@cache mutable struct ImplicitEulerCache{ - uType, rateType, uNoUnitsType, N, AV, StepLimiter} <: - SDIRKMutableCache - u::uType - uprev::uType - uprev2::uType - fsalfirst::rateType - atmp::uNoUnitsType - nlsolver::N - algebraic_vars::AV - step_limiter!::StepLimiter -end - -function alg_cache(alg::ImplicitEuler, u, rate_prototype, ::Type{uEltypeNoUnits}, - ::Type{uBottomEltypeNoUnits}, - ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, - ::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - γ, c = 1, 1 - nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, - uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(true)) - fsalfirst = zero(rate_prototype) - - atmp = similar(u, uEltypeNoUnits) - recursivefill!(atmp, false) - - algebraic_vars = f.mass_matrix === I ? nothing : - [all(iszero, x) for x in eachcol(f.mass_matrix)] - - ImplicitEulerCache( - u, uprev, uprev2, fsalfirst, atmp, nlsolver, algebraic_vars, alg.step_limiter!) -end - -mutable struct ImplicitEulerConstantCache{N} <: OrdinaryDiffEqConstantCache - nlsolver::N -end - @cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: OrdinaryDiffEqConstantCache nlsolver::N From 7a7c0ef26aaf028491c4dd5de7c219c34eb33725 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Mon, 15 Jul 2024 00:05:52 +0530 Subject: [PATCH 032/112] Cache --- src/OrdinaryDiffEq.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 2d5288099d..2cd4fba49c 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -155,6 +155,8 @@ include("caches/linear_nonlinear_caches.jl") include("caches/rosenbrock_caches.jl") include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") +include("../lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl") +include("caches/bdf_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") include("caches/dae_caches.jl") @@ -282,8 +284,6 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA -include("caches/bdf_caches.jl") - import PrecompileTools PrecompileTools.@compile_workload begin From 2109ca9d114e7c3d7f9d7a1bccc3127188d74950 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Mon, 15 Jul 2024 08:54:30 +0530 Subject: [PATCH 033/112] ImplicitEulerCache --- src/caches/bdf_caches.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/caches/bdf_caches.jl b/src/caches/bdf_caches.jl index 78a64c7c7b..b401fb4f32 100644 --- a/src/caches/bdf_caches.jl +++ b/src/caches/bdf_caches.jl @@ -1,3 +1,4 @@ +using OrdinaryDiffEq @cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: OrdinaryDiffEqConstantCache nlsolver::N From d1a0819bdd7baa798130eaee085ce4980ed87e7a Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Mon, 15 Jul 2024 08:56:54 +0530 Subject: [PATCH 034/112] ImplicitEulerCache --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- src/caches/bdf_caches.jl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 328901df20..19fb02f3bd 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -2,8 +2,8 @@ module OrdinaryDiffEqSDIRK include("algorithms.jl") include("alg_utils.jl") -include("sdirk_caches.jl") include("kencarp_kvaerno_caches.jl") +include("sdirk_caches.jl") include("sdirk_perform_step.jl") include("kencarp_kvaerno_perform_step.jl") include("sdirk_tableaus.jl") diff --git a/src/caches/bdf_caches.jl b/src/caches/bdf_caches.jl index b401fb4f32..78a64c7c7b 100644 --- a/src/caches/bdf_caches.jl +++ b/src/caches/bdf_caches.jl @@ -1,4 +1,3 @@ -using OrdinaryDiffEq @cache mutable struct ABDF2ConstantCache{N, dtType, rate_prototype} <: OrdinaryDiffEqConstantCache nlsolver::N From 8f8fd3e455a787bd99ff7b5b43fa8a614e2dca2f Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Mon, 15 Jul 2024 09:01:12 +0530 Subject: [PATCH 035/112] ImplicitEuler --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 19fb02f3bd..6450242c33 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -1,5 +1,17 @@ module OrdinaryDiffEqSDIRK +import OrdinaryDiffEq: alg_order, calculate_residuals!, + initialize!, perform_step!, @unpack, unwrap_alg, + calculate_residuals, alg_extrapolates, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqAdaptivePartitionedAlgorithm, + OrdinaryDiffEqPartitionedAlgorithm, + OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, + alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, + trivial_limiter!, _ode_interpolant!, _ode_addsteps! + include("algorithms.jl") include("alg_utils.jl") include("kencarp_kvaerno_caches.jl") From 266ff4eef7306f2cc1ffe0adda91ed448de65278 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Tue, 16 Jul 2024 10:47:47 +0530 Subject: [PATCH 036/112] Changes made --- lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl | 9 ++++++++- src/algorithms.jl | 1 - 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl index 50684fb185..714bf60ded 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl @@ -45,4 +45,11 @@ alg_adaptive_order(alg::ImplicitEuler) = 0 ssp_coefficient(alg::SSPSDIRK2) = 4 -isesdirk(alg::TRBDF2) = true \ No newline at end of file +isesdirk(alg::TRBDF2) = true + +issplit(alg::KenCarp3) = true +issplit(alg::KenCarp4) = true +issplit(alg::KenCarp47) = true +issplit(alg::KenCarp5) = true +issplit(alg::KenCarp58) = true +issplit(alg::CFNLIRK3) = true \ No newline at end of file diff --git a/src/algorithms.jl b/src/algorithms.jl index d5994e4eba..0b5dfad506 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -1430,7 +1430,6 @@ const MultistepAlgorithms = Union{ ABDF2, AB3, AB4, AB5, ABM32, ABM43, ABM54} -#KenCarp3, KenCarp4, KenCarp47, KenCarp5, KenCarp58, CFNLIRK3 const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF} #= From 611b058672e14f2983ab66b7925d1c1ef951a426 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Wed, 17 Jul 2024 15:31:08 -0400 Subject: [PATCH 037/112] Update src/OrdinaryDiffEq.jl --- src/OrdinaryDiffEq.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 2cd4fba49c..a6057ab5ad 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -155,7 +155,6 @@ include("caches/linear_nonlinear_caches.jl") include("caches/rosenbrock_caches.jl") include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") -include("../lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl") include("caches/bdf_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") From 3478d8951727ae0f4fde4625c092de400636e402 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Wed, 17 Jul 2024 15:40:16 -0400 Subject: [PATCH 038/112] Update OrdinaryDiffEq.jl --- src/OrdinaryDiffEq.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index a6057ab5ad..66871fd93e 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -155,7 +155,6 @@ include("caches/linear_nonlinear_caches.jl") include("caches/rosenbrock_caches.jl") include("caches/adams_bashforth_moulton_caches.jl") include("caches/nordsieck_caches.jl") -include("caches/bdf_caches.jl") include("caches/prk_caches.jl") include("caches/pdirk_caches.jl") include("caches/dae_caches.jl") @@ -188,7 +187,6 @@ include("perform_step/rosenbrock_perform_step.jl") include("perform_step/composite_perform_step.jl") include("perform_step/adams_bashforth_moulton_perform_step.jl") include("perform_step/nordsieck_perform_step.jl") -include("perform_step/bdf_perform_step.jl") include("perform_step/prk_perform_step.jl") include("perform_step/pdirk_perform_step.jl") include("perform_step/dae_perform_step.jl") @@ -204,7 +202,6 @@ include("dense/high_order_rk_addsteps.jl") include("derivative_utils.jl") include("nordsieck_utils.jl") include("adams_utils.jl") -include("bdf_utils.jl") include("derivative_wrappers.jl") include("iterator_interface.jl") include("constants.jl") @@ -283,6 +280,10 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA +include("caches/bdf_caches.jl") +include("perform_step/bdf_perform_step.jl") +include("bdf_utils.jl") + import PrecompileTools PrecompileTools.@compile_workload begin From 0b158e2114c6bb0a946e7f2168a3ac801437271c Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Wed, 17 Jul 2024 15:46:30 -0400 Subject: [PATCH 039/112] Update lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 6450242c33..9969f2b183 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -5,7 +5,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, calculate_residuals, alg_extrapolates, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, - OrdinaryDiffEqAdaptivePartitionedAlgorithm, + OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqPartitionedAlgorithm, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, From 0ea8ef51cba59fb2f752e0b350f8ef876cef9a05 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 07:33:00 +0530 Subject: [PATCH 040/112] OrdinaryDiffEqNewtonAlgorithm --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 9969f2b183..eee4f07764 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -7,6 +7,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqPartitionedAlgorithm, + OrdinaryDiffEqNewtonAlgorithm, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, From 8116a558e42afc4cd6b3a9a1bdcb6b081cde9828 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 07:37:51 +0530 Subject: [PATCH 041/112] TruncatedStackTraces --- lib/OrdinaryDiffEqSDIRK/Project.toml | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index db13e6df07..33fdb35baf 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -5,6 +5,7 @@ version = "1.0.0" [deps] OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index eee4f07764..e5279d9cab 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -6,12 +6,12 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, OrdinaryDiffEqNewtonAdaptiveAlgorithm, - OrdinaryDiffEqPartitionedAlgorithm, OrdinaryDiffEqNewtonAlgorithm, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! +using TruncatedStacktraces include("algorithms.jl") include("alg_utils.jl") From 0c24522fce7f4cc27271d33457228ea135ad170d Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 07:40:33 +0530 Subject: [PATCH 042/112] SDIRKMutableCache --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index e5279d9cab..6173ce0f50 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -15,8 +15,8 @@ using TruncatedStacktraces include("algorithms.jl") include("alg_utils.jl") -include("kencarp_kvaerno_caches.jl") include("sdirk_caches.jl") +include("kencarp_kvaerno_caches.jl") include("sdirk_perform_step.jl") include("kencarp_kvaerno_perform_step.jl") include("sdirk_tableaus.jl") From 529417fc7c9c737b33d763fb5cf015564f1bcb2a Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 07:47:13 +0530 Subject: [PATCH 043/112] MuladdMacro --- lib/OrdinaryDiffEqSDIRK/Project.toml | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 33fdb35baf..2b72b8167f 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -6,6 +6,7 @@ version = "1.0.0" [deps] OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 6173ce0f50..9b5913902c 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -11,7 +11,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using TruncatedStacktraces +using TruncatedStacktraces, MuladdMacro include("algorithms.jl") include("alg_utils.jl") From 962ed21f934a11e630055a2e5ba98c77ca16a074 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 07:53:45 +0530 Subject: [PATCH 044/112] MacroTools --- lib/OrdinaryDiffEqSDIRK/Project.toml | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 2b72b8167f..3396719d3a 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -7,6 +7,7 @@ version = "1.0.0" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 9b5913902c..9e47cba45f 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -11,7 +11,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using TruncatedStacktraces, MuladdMacro +using TruncatedStacktraces, MuladdMacro, MacroTools include("algorithms.jl") include("alg_utils.jl") From 2074723f74bc4d984d6b9d051bc11fd6f47da836 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 08:03:49 +0530 Subject: [PATCH 045/112] @.. --- lib/OrdinaryDiffEqSDIRK/Project.toml | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 3396719d3a..3e292e6216 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -8,6 +8,7 @@ OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 9e47cba45f..41719f3d5f 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -11,7 +11,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using TruncatedStacktraces, MuladdMacro, MacroTools +using TruncatedStacktraces, MuladdMacro, MacroTools, RecursiveArrayTools include("algorithms.jl") include("alg_utils.jl") From a3360d742f5df1296bdfce20df7f0d4717c0ef17 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 08:14:40 +0530 Subject: [PATCH 046/112] @.. --- lib/OrdinaryDiffEqSDIRK/Project.toml | 2 +- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 3e292e6216..2fb44a896d 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -8,7 +8,7 @@ OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 41719f3d5f..7dca8156e8 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -11,7 +11,9 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using TruncatedStacktraces, MuladdMacro, MacroTools, RecursiveArrayTools +using TruncatedStacktraces, MuladdMacro, MacroTools +using DiffEqBase: @def, @tight_loop_macros +using Static: False include("algorithms.jl") include("alg_utils.jl") From de2240950fb6f278cdad576f60aa7bb057bc050e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 08:15:07 +0530 Subject: [PATCH 047/112] @.. --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 7dca8156e8..c37b3b58c4 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -11,7 +11,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using TruncatedStacktraces, MuladdMacro, MacroTools +using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast using DiffEqBase: @def, @tight_loop_macros using Static: False From 863b6196c2138c628f591dc8e02058c9beddf250 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 08:47:20 +0530 Subject: [PATCH 048/112] Fixes --- lib/OrdinaryDiffEqBDF/Project.toml | 4 + .../src/OrdinaryDiffEqBDF.jl | 25 ++ lib/OrdinaryDiffEqBDF/src/alg_utils.jl | 24 ++ lib/OrdinaryDiffEqBDF/src/algorithms.jl | 390 ++++++++++++++++++ .../OrdinaryDiffEqBDF/src}/bdf_caches.jl | 2 +- .../src}/bdf_perform_step.jl | 2 +- .../OrdinaryDiffEqBDF/src}/bdf_utils.jl | 2 +- .../src/OrdinaryDiffEqSDIRK.jl | 2 - src/OrdinaryDiffEq.jl | 13 +- src/alg_utils.jl | 21 - src/algorithms.jl | 390 ------------------ 11 files changed, 450 insertions(+), 425 deletions(-) create mode 100644 lib/OrdinaryDiffEqBDF/Project.toml create mode 100644 lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl create mode 100644 lib/OrdinaryDiffEqBDF/src/alg_utils.jl create mode 100644 lib/OrdinaryDiffEqBDF/src/algorithms.jl rename {src/caches => lib/OrdinaryDiffEqBDF/src}/bdf_caches.jl (99%) rename {src/perform_step => lib/OrdinaryDiffEqBDF/src}/bdf_perform_step.jl (99%) rename {src => lib/OrdinaryDiffEqBDF/src}/bdf_utils.jl (99%) diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml new file mode 100644 index 0000000000..36df9f7b00 --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -0,0 +1,4 @@ +name = "OrdinaryDiffEqBDF" +uuid = "6ad6398a-0878-4a85-9266-38940aa047c8" +authors = ["ParamThakkar123 "] +version = "0.1.0" diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl new file mode 100644 index 0000000000..e952b9c661 --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -0,0 +1,25 @@ +module OrdinaryDiffEqBDF + +import OrdinaryDiffEq: alg_order, calculate_residuals!, + initialize!, perform_step!, @unpack, unwrap_alg, + calculate_residuals, alg_extrapolates, + OrdinaryDiffEqAlgorithm, + OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, + OrdinaryDiffEqNewtonAdaptiveAlgorithm, + OrdinaryDiffEqNewtonAlgorithm, + OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, + alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, + trivial_limiter!, _ode_interpolant!, _ode_addsteps! +using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast + +include("algorithms.jl") +include("alg_utils.jl") +include("bdf_caches.jl") +include("bdf_utils.jl") +include("bdf_perform_step.jl") + +export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, + SBDF2, SBDF3, SBDF4, MEBDF2 + +end diff --git a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl new file mode 100644 index 0000000000..64b61451f0 --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl @@ -0,0 +1,24 @@ +alg_extrapolates(alg::ABDF2) = true +alg_extrapolates(alg::SBDF) = true +alg_extrapolates(alg::MEBDF2) = true + +alg_order(alg::ABDF2) = 2 +alg_order(alg::SBDF) = alg.order +alg_order(alg::QNDF1) = 1 +alg_order(alg::QNDF2) = 2 +alg_order(alg::QNDF) = 1 #dummy value +alg_order(alg::MEBDF2) = 2 +alg_order(alg::FBDF) = 1 #dummy value + +qsteady_min_default(alg::FBDF) = 9 // 10 + +qsteady_max_default(alg::QNDF) = 2 // 1 +qsteady_max_default(alg::QNDF2) = 2 // 1 +qsteady_max_default(alg::QNDF1) = 2 // 1 +qsteady_max_default(alg::FBDF) = 2 // 1 + +get_current_alg_order(alg::QNDF, cache) = cache.order +get_current_alg_order(alg::FBDF, cache) = cache.order + +get_current_adaptive_order(alg::QNDF, cache) = cache.order +get_current_adaptive_order(alg::FBDF, cache) = cache.order \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl new file mode 100644 index 0000000000..4862ee2daf --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -0,0 +1,390 @@ +""" +E. Alberdi Celayaa, J. J. Anza Aguirrezabalab, P. Chatzipantelidisc. Implementation of +an Adaptive BDF2 Formula and Comparison with The MATLAB Ode15s. Procedia Computer Science, +29, pp 1014-1026, 2014. doi: https://doi.org/10.1016/j.procs.2014.05.091 + +ABDF2: Multistep Method +An adaptive order 2 L-stable fixed leading coefficient multistep BDF method. +""" +struct ABDF2{CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + smooth_est::Bool + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end +function ABDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + κ = nothing, tol = nothing, linsolve = nothing, precs = DEFAULT_PRECS, + nlsolve = NLNewton(), + smooth_est = true, extrapolant = :linear, + controller = :Standard, step_limiter! = trivial_limiter!) + ABDF2{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(step_limiter!)}(linsolve, nlsolve, precs, κ, tol, + smooth_est, extrapolant, controller, step_limiter!) +end + +""" +Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. Implicit-Explicit Methods for Time- +Dependent Partial Differential Equations. 1995 Society for Industrial and Applied Mathematics +Journal on Numerical Analysis, 32(3), pp 797-823, 1995. doi: https://doi.org/10.1137/0732037 +""" +struct SBDF{CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + order::Int + ark::Bool +end + +function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), + standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, ark = false) + SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(linsolve, + nlsolve, + precs, + κ, + tol, + extrapolant, + order, + ark) +end + +# All keyword form needed for remake +function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, + order, ark = false) + SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(κ), typeof(tol)}(linsolve, + nlsolve, + precs, + κ, + tol, + extrapolant, + order, + ark) +end + +""" + IMEXEuler(;kwargs...) + +The one-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +When applied to a `SplitODEProblem` of the form + +``` +u'(t) = f1(u) + f2(u) +``` + +The default `IMEXEuler()` method uses an update of the form + +``` +unew = uold + dt * (f1(unew) + f2(uold)) +``` + +See also `SBDF`, `IMEXEulerARK`. +""" +IMEXEuler(; kwargs...) = SBDF(1; kwargs...) + +""" + IMEXEulerARK(;kwargs...) + +The one-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +When applied to a `SplitODEProblem` of the form + +``` +u'(t) = f1(u) + f2(u) +``` + +A classical additive Runge-Kutta method in the sense of +[Araújo, Murua, Sanz-Serna (1997)](https://doi.org/10.1137/S0036142995292128) +consisting of the implicit and the explicit Euler method given by + +``` +y1 = uold + dt * f1(y1) +unew = uold + dt * (f1(unew) + f2(y1)) +``` + +See also `SBDF`, `IMEXEuler`. +""" +IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) + +""" + SBDF2(;kwargs...) + +The two-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +See also `SBDF`. +""" +SBDF2(; kwargs...) = SBDF(2; kwargs...) + +""" + SBDF3(;kwargs...) + +The three-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +See also `SBDF`. +""" +SBDF3(; kwargs...) = SBDF(3; kwargs...) + +""" + SBDF4(;kwargs...) + +The four-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +See also `SBDF`. +""" +SBDF4(; kwargs...) = SBDF(4; kwargs...) + +""" +QNDF1: Multistep Method +An adaptive order 1 quasi-constant timestep L-stable numerical differentiation function (NDF) method. +Optional parameter kappa defaults to Shampine's accuracy-optimal -0.1850. + +See also `QNDF`. +""" +struct QNDF1{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, kappa = -0.1850, + controller = :Standard, step_limiter! = trivial_limiter!) + QNDF1{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(kappa), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + kappa, + controller, + step_limiter!) +end + +""" +QNDF2: Multistep Method +An adaptive order 2 quasi-constant timestep L-stable numerical differentiation function (NDF) method. + +See also `QNDF`. +""" +struct QNDF2{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :linear, kappa = -1 // 9, + controller = :Standard, step_limiter! = trivial_limiter!) + QNDF2{ + _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), + typeof(kappa), typeof(step_limiter!)}(linsolve, + nlsolve, + precs, + extrapolant, + kappa, + controller, + step_limiter!) +end + +""" +QNDF: Multistep Method +An adaptive order quasi-constant timestep NDF method. +Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). + +@article{shampine1997matlab, +title={The matlab ode suite}, +author={Shampine, Lawrence F and Reichelt, Mark W}, +journal={SIAM journal on scientific computing}, +volume={18}, +number={1}, +pages={1--22}, +year={1997}, +publisher={SIAM} +} +""" +struct QNDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, κType, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + kappa::κType + controller::Symbol + step_limiter!::StepLimiter +end + +function QNDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, kappa = promote(-0.1850, -1 // 9, -0.0823, -0.0415, 0), + controller = :Standard, step_limiter! = trivial_limiter!) where {MO} + QNDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(kappa), typeof(step_limiter!)}( + max_order, linsolve, nlsolve, precs, κ, tol, + extrapolant, kappa, controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace QNDF + +""" +MEBDF2: Multistep Method +The second order Modified Extended BDF method, which has improved stability properties over the standard BDF. +Fixed timestep only. +""" +struct MEBDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: + OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} + linsolve::F + nlsolve::F2 + precs::P + extrapolant::Symbol +end +function MEBDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), + extrapolant = :constant) + MEBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac)}(linsolve, + nlsolve, + precs, + extrapolant) +end + +""" +FBDF: Fixed leading coefficient BDF + +An adaptive order quasi-constant timestep NDF method. +Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). + +@article{shampine2002solving, +title={Solving 0= F (t, y (t), y′(t)) in Matlab}, +author={Shampine, Lawrence F}, +year={2002}, +publisher={Walter de Gruyter GmbH \\& Co. KG} +} +""" +struct FBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: + OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} + max_order::Val{MO} + linsolve::F + nlsolve::F2 + precs::P + κ::K + tol::T + extrapolant::Symbol + controller::Symbol + step_limiter!::StepLimiter +end + +function FBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), + autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, + linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, + tol = nothing, + extrapolant = :linear, controller = :Standard, step_limiter! = trivial_limiter!) where {MO} + FBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), + _unwrap_val(concrete_jac), + typeof(κ), typeof(tol), typeof(step_limiter!)}( + max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, + controller, step_limiter!) +end + +TruncatedStacktraces.@truncate_stacktrace FBDF + +""" +QBDF1: Multistep Method + +An alias of `QNDF1` with κ=0. +""" +QBDF1(; kwargs...) = QNDF1(; kappa = 0, kwargs...) + +""" +QBDF2: Multistep Method + +An alias of `QNDF2` with κ=0. +""" +QBDF2(; kwargs...) = QNDF2(; kappa = 0, kwargs...) + +""" +QBDF: Multistep Method + +An alias of `QNDF` with κ=0. +""" +QBDF(; kwargs...) = QNDF(; kappa = tuple(0 // 1, 0 // 1, 0 // 1, 0 // 1, 0 // 1), kwargs...) \ No newline at end of file diff --git a/src/caches/bdf_caches.jl b/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl similarity index 99% rename from src/caches/bdf_caches.jl rename to lib/OrdinaryDiffEqBDF/src/bdf_caches.jl index 78a64c7c7b..f15cb8006b 100644 --- a/src/caches/bdf_caches.jl +++ b/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl @@ -655,4 +655,4 @@ function alg_cache(alg::FBDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, iters_from_event, alg.step_limiter!) -end +end \ No newline at end of file diff --git a/src/perform_step/bdf_perform_step.jl b/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl similarity index 99% rename from src/perform_step/bdf_perform_step.jl rename to lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl index e52686c8cc..082d4faa03 100644 --- a/src/perform_step/bdf_perform_step.jl +++ b/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl @@ -1342,4 +1342,4 @@ function perform_step!(integrator, cache::FBDFCache{max_order}, f(integrator.fsallast, u, p, tdt) integrator.stats.nf += 1 -end +end \ No newline at end of file diff --git a/src/bdf_utils.jl b/lib/OrdinaryDiffEqBDF/src/bdf_utils.jl similarity index 99% rename from src/bdf_utils.jl rename to lib/OrdinaryDiffEqBDF/src/bdf_utils.jl index 29c0e696b0..a89682ba5b 100644 --- a/src/bdf_utils.jl +++ b/lib/OrdinaryDiffEqBDF/src/bdf_utils.jl @@ -272,4 +272,4 @@ function estimate_terk(integrator, cache, k, ::Val{max_order}, u) where {max_ord terk *= abs(dt^(k - 1)) end return terk -end +end \ No newline at end of file diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index c37b3b58c4..05b6bcae6f 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,8 +12,6 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast -using DiffEqBase: @def, @tight_loop_macros -using Static: False include("algorithms.jl") include("alg_utils.jl") diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 66871fd93e..de666cc8c4 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -280,9 +280,10 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA -include("caches/bdf_caches.jl") -include("perform_step/bdf_perform_step.jl") -include("bdf_utils.jl") +include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") +using ..OrdinaryDiffEqBDF +export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, + SBDF2, SBDF3, SBDF4, MEBDF2 import PrecompileTools @@ -451,12 +452,6 @@ export IMEXEuler, IMEXEulerARK, CNAB2, CNLF2 export AN5, JVODE, JVODE_Adams, JVODE_BDF -export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF - -export SBDF2, SBDF3, SBDF4 - -export MEBDF2 - export Alshina2, Alshina3, Alshina6 export AutoSwitch, AutoTsit5, AutoDP5, diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 5cc5d7644e..081be3f77a 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -349,9 +349,6 @@ alg_extrapolates(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false alg_extrapolates(alg::CompositeAlgorithm) = any(alg_extrapolates.(alg.algs)) alg_extrapolates(alg::DImplicitEuler) = true alg_extrapolates(alg::DABDF2) = true -alg_extrapolates(alg::ABDF2) = true -alg_extrapolates(alg::SBDF) = true -alg_extrapolates(alg::MEBDF2) = true alg_extrapolates(alg::MagnusLeapfrog) = true function alg_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) @@ -371,10 +368,6 @@ function get_current_adaptive_order(alg::OrdinaryDiffEqAdamsVarOrderVarStepAlgor cache.order end get_current_alg_order(alg::JVODE, cache) = get_current_adaptive_order(alg, cache) -get_current_alg_order(alg::QNDF, cache) = cache.order -get_current_alg_order(alg::FBDF, cache) = cache.order -get_current_adaptive_order(alg::QNDF, cache) = cache.order -get_current_adaptive_order(alg::FBDF, cache) = cache.order #alg_adaptive_order(alg::OrdinaryDiffEqAdaptiveAlgorithm) = error("Algorithm is adaptive with no order") function get_current_adaptive_order(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}, @@ -514,16 +507,7 @@ alg_order(alg::CNLF2) = 2 alg_order(alg::AN5) = 5 alg_order(alg::JVODE) = 1 #dummy value -alg_order(alg::ABDF2) = 2 -alg_order(alg::QNDF1) = 1 -alg_order(alg::QNDF2) = 2 -alg_order(alg::QNDF) = 1 #dummy value -alg_order(alg::FBDF) = 1 #dummy value - -alg_order(alg::SBDF) = alg.order - -alg_order(alg::MEBDF2) = 2 alg_order(alg::PDIRK44) = 4 alg_order(alg::DImplicitEuler) = 1 @@ -609,17 +593,12 @@ gamma_default(alg::CompositeAlgorithm) = maximum(gamma_default, alg.algs) fac_default_gamma(alg) = false qsteady_min_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 1 -qsteady_min_default(alg::FBDF) = 9 // 10 qsteady_max_default(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = 1 qsteady_max_default(alg::OrdinaryDiffEqAdaptiveImplicitAlgorithm) = 6 // 5 # But don't re-use Jacobian if not adaptive: too risky and cannot pull back qsteady_max_default(alg::OrdinaryDiffEqImplicitAlgorithm) = isadaptive(alg) ? 1 // 1 : 0 qsteady_max_default(alg::AN5) = 3 // 2 qsteady_max_default(alg::JVODE) = 3 // 2 -qsteady_max_default(alg::QNDF1) = 2 // 1 -qsteady_max_default(alg::QNDF2) = 2 // 1 -qsteady_max_default(alg::QNDF) = 2 // 1 -qsteady_max_default(alg::FBDF) = 2 // 1 #TODO #DiffEqBase.nlsolve_default(::QNDF, ::Val{κ}) = 1//2 diff --git a/src/algorithms.jl b/src/algorithms.jl index 0b5dfad506..59df354267 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -490,340 +490,6 @@ function CNLF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Va extrapolant) end -""" -QNDF1: Multistep Method -An adaptive order 1 quasi-constant timestep L-stable numerical differentiation function (NDF) method. -Optional parameter kappa defaults to Shampine's accuracy-optimal -0.1850. - -See also `QNDF`. -""" -struct QNDF1{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, kappa = -0.1850, - controller = :Standard, step_limiter! = trivial_limiter!) - QNDF1{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(kappa), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - kappa, - controller, - step_limiter!) -end - -""" -QBDF1: Multistep Method - -An alias of `QNDF1` with κ=0. -""" -QBDF1(; kwargs...) = QNDF1(; kappa = 0, kwargs...) - -""" -QNDF2: Multistep Method -An adaptive order 2 quasi-constant timestep L-stable numerical differentiation function (NDF) method. - -See also `QNDF`. -""" -struct QNDF2{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :linear, kappa = -1 // 9, - controller = :Standard, step_limiter! = trivial_limiter!) - QNDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(kappa), typeof(step_limiter!)}(linsolve, - nlsolve, - precs, - extrapolant, - kappa, - controller, - step_limiter!) -end - -""" -QBDF2: Multistep Method - -An alias of `QNDF2` with κ=0. -""" -QBDF2(; kwargs...) = QNDF2(; kappa = 0, kwargs...) - -""" -QNDF: Multistep Method -An adaptive order quasi-constant timestep NDF method. -Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). - -@article{shampine1997matlab, -title={The matlab ode suite}, -author={Shampine, Lawrence F and Reichelt, Mark W}, -journal={SIAM journal on scientific computing}, -volume={18}, -number={1}, -pages={1--22}, -year={1997}, -publisher={SIAM} -} -""" -struct QNDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, κType, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - kappa::κType - controller::Symbol - step_limiter!::StepLimiter -end - -function QNDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, kappa = promote(-0.1850, -1 // 9, -0.0823, -0.0415, 0), - controller = :Standard, step_limiter! = trivial_limiter!) where {MO} - QNDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(kappa), typeof(step_limiter!)}( - max_order, linsolve, nlsolve, precs, κ, tol, - extrapolant, kappa, controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace QNDF - -""" -QBDF: Multistep Method - -An alias of `QNDF` with κ=0. -""" -QBDF(; kwargs...) = QNDF(; kappa = tuple(0 // 1, 0 // 1, 0 // 1, 0 // 1, 0 // 1), kwargs...) - -""" -FBDF: Fixed leading coefficient BDF - -An adaptive order quasi-constant timestep NDF method. -Utilizes Shampine's accuracy-optimal kappa values as defaults (has a keyword argument for a tuple of kappa coefficients). - -@article{shampine2002solving, -title={Solving 0= F (t, y (t), y′(t)) in Matlab}, -author={Shampine, Lawrence F}, -year={2002}, -publisher={Walter de Gruyter GmbH \\& Co. KG} -} -""" -struct FBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - max_order::Val{MO} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end - -function FBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, controller = :Standard, step_limiter! = trivial_limiter!) where {MO} - FBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(step_limiter!)}( - max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller, step_limiter!) -end - -TruncatedStacktraces.@truncate_stacktrace FBDF - -""" -Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. Implicit-Explicit Methods for Time- -Dependent Partial Differential Equations. 1995 Society for Industrial and Applied Mathematics -Journal on Numerical Analysis, 32(3), pp 797-823, 1995. doi: https://doi.org/10.1137/0732037 -""" -struct SBDF{CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - extrapolant::Symbol - order::Int - ark::Bool -end - -function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, ark = false) - SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(linsolve, - nlsolve, - precs, - κ, - tol, - extrapolant, - order, - ark) -end - -# All keyword form needed for remake -function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, - tol = nothing, - extrapolant = :linear, - order, ark = false) - SBDF{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol)}(linsolve, - nlsolve, - precs, - κ, - tol, - extrapolant, - order, - ark) -end - -""" - IMEXEuler(;kwargs...) - -The one-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -When applied to a `SplitODEProblem` of the form - -``` -u'(t) = f1(u) + f2(u) -``` - -The default `IMEXEuler()` method uses an update of the form - -``` -unew = uold + dt * (f1(unew) + f2(uold)) -``` - -See also `SBDF`, `IMEXEulerARK`. -""" -IMEXEuler(; kwargs...) = SBDF(1; kwargs...) - -""" - IMEXEulerARK(;kwargs...) - -The one-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -When applied to a `SplitODEProblem` of the form - -``` -u'(t) = f1(u) + f2(u) -``` - -A classical additive Runge-Kutta method in the sense of -[Araújo, Murua, Sanz-Serna (1997)](https://doi.org/10.1137/S0036142995292128) -consisting of the implicit and the explicit Euler method given by - -``` -y1 = uold + dt * f1(y1) -unew = uold + dt * (f1(unew) + f2(y1)) -``` - -See also `SBDF`, `IMEXEuler`. -""" -IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) - -""" - SBDF2(;kwargs...) - -The two-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -See also `SBDF`. -""" -SBDF2(; kwargs...) = SBDF(2; kwargs...) - -""" - SBDF3(;kwargs...) - -The three-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -See also `SBDF`. -""" -SBDF3(; kwargs...) = SBDF(3; kwargs...) - -""" - SBDF4(;kwargs...) - -The four-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -See also `SBDF`. -""" -SBDF4(; kwargs...) = SBDF(4; kwargs...) - # Adams/BDF methods in Nordsieck forms """ AN5: Adaptive step size Adams explicit Method @@ -1272,39 +938,6 @@ struct ETD2 <: ######################################### -""" -E. Alberdi Celayaa, J. J. Anza Aguirrezabalab, P. Chatzipantelidisc. Implementation of -an Adaptive BDF2 Formula and Comparison with The MATLAB Ode15s. Procedia Computer Science, -29, pp 1014-1026, 2014. doi: https://doi.org/10.1016/j.procs.2014.05.091 - -ABDF2: Multistep Method -An adaptive order 2 L-stable fixed leading coefficient multistep BDF method. -""" -struct ABDF2{CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: - OrdinaryDiffEqNewtonAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - κ::K - tol::T - smooth_est::Bool - extrapolant::Symbol - controller::Symbol - step_limiter!::StepLimiter -end -function ABDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - κ = nothing, tol = nothing, linsolve = nothing, precs = DEFAULT_PRECS, - nlsolve = NLNewton(), - smooth_est = true, extrapolant = :linear, - controller = :Standard, step_limiter! = trivial_limiter!) - ABDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), - typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), - typeof(κ), typeof(tol), typeof(step_limiter!)}(linsolve, nlsolve, precs, κ, tol, - smooth_est, extrapolant, controller, step_limiter!) -end - ######################################### struct CompositeAlgorithm{CS, T, F} <: OrdinaryDiffEqCompositeAlgorithm @@ -1378,29 +1011,6 @@ struct AutoSwitch{nAlg, sAlg, tolType, T} end ################################################################################ -""" -MEBDF2: Multistep Method -The second order Modified Extended BDF method, which has improved stability properties over the standard BDF. -Fixed timestep only. -""" -struct MEBDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: - OrdinaryDiffEqNewtonAlgorithm{CS, AD, FDT, ST, CJ} - linsolve::F - nlsolve::F2 - precs::P - extrapolant::Symbol -end -function MEBDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, - linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), - extrapolant = :constant) - MEBDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), - typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), - _unwrap_val(concrete_jac)}(linsolve, - nlsolve, - precs, - extrapolant) -end ################################################# """ From 0ab4fbadf857735c498811927b7d29567d0bdd55 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 08:50:44 +0530 Subject: [PATCH 049/112] Fixes --- src/algorithms.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/algorithms.jl b/src/algorithms.jl index 59df354267..3e7d67a3bf 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -1036,8 +1036,8 @@ function PDIRK44(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{tru end ### Algorithm Groups +# ABDF2 const MultistepAlgorithms = Union{ - ABDF2, AB3, AB4, AB5, ABM32, ABM43, ABM54} const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF} From 09260263c71fc3c40d56856a8cb555c46121faca Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 09:09:32 +0530 Subject: [PATCH 050/112] SBDF --- lib/OrdinaryDiffEqBDF/src/alg_utils.jl | 2 ++ src/algorithms.jl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl index 64b61451f0..d5c93df0c1 100644 --- a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl @@ -10,6 +10,8 @@ alg_order(alg::QNDF) = 1 #dummy value alg_order(alg::MEBDF2) = 2 alg_order(alg::FBDF) = 1 #dummy value +issplit(alg::SBDF) = true + qsteady_min_default(alg::FBDF) = 9 // 10 qsteady_max_default(alg::QNDF) = 2 // 1 diff --git a/src/algorithms.jl b/src/algorithms.jl index 3e7d67a3bf..60a22278d6 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -1040,7 +1040,7 @@ end const MultistepAlgorithms = Union{ AB3, AB4, AB5, ABM32, ABM43, ABM54} -const SplitAlgorithms = Union{CNAB2, CNLF2, SBDF} +const SplitAlgorithms = Union{CNAB2, CNLF2} #= struct DBDF{CS,AD,F,F2,P,FDT,ST,CJ} <: DAEAlgorithm{CS,AD,FDT,ST,CJ} From 21d1fd873a2c278b212150af0891588291c3649e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 09:19:27 +0530 Subject: [PATCH 051/112] BDF --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 1 + lib/OrdinaryDiffEqBDF/src/controllers.jl | 6 ++++++ src/alg_utils.jl | 9 ++------- src/integrators/controllers.jl | 2 -- 4 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 lib/OrdinaryDiffEqBDF/src/controllers.jl diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index e952b9c661..c584d0b06d 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -15,6 +15,7 @@ using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast include("algorithms.jl") include("alg_utils.jl") +include("controllers.jl") include("bdf_caches.jl") include("bdf_utils.jl") include("bdf_perform_step.jl") diff --git a/lib/OrdinaryDiffEqBDF/src/controllers.jl b/lib/OrdinaryDiffEqBDF/src/controllers.jl new file mode 100644 index 0000000000..4e6fb7675b --- /dev/null +++ b/lib/OrdinaryDiffEqBDF/src/controllers.jl @@ -0,0 +1,6 @@ +struct DummyController <: AbstractController +end + +function default_controller(alg::Union{QNDF, FBDF}, args...) + DummyController() +end \ No newline at end of file diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 081be3f77a..839f0e468c 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -567,7 +567,7 @@ function _digest_beta1_beta2(alg, cache, ::Val{QT}, _beta1, _beta2) where {QT} end # other special cases in controllers.jl -function default_controller(alg::Union{JVODE, QNDF, FBDF}, args...) +function default_controller(alg::Union{JVODE}, args...) DummyController() end @@ -698,9 +698,4 @@ isesdirk(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::CompositeAlgorithm) = all(is_mass_matrix_alg, alg.algs) is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true -is_mass_matrix_alg(alg::NewtonAlgorithm) = !isesdirk(alg) -# hack for the default alg -function is_mass_matrix_alg(alg::CompositeAlgorithm{ - <:Any, <:Tuple{Tsit5, Rosenbrock23, Rodas5P, FBDF, FBDF}}) - true -end +is_mass_matrix_alg(alg::NewtonAlgorithm) = !isesdirk(alg) \ No newline at end of file diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index 416a6ea99d..58adbb4dc7 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -448,8 +448,6 @@ end # Dummy controller without any method implementations. # This is used to transfer the special controllers associated to certain # algorithms to the new controller infrastructure with -struct DummyController <: AbstractController -end # JVODE function stepsize_controller!(integrator, alg::JVODE) From d3881c9dd0b7d7658e9628746a3907ae09ce74cb Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 09:35:33 +0530 Subject: [PATCH 052/112] controllers --- lib/OrdinaryDiffEqBDF/src/controllers.jl | 217 +++++++++++++++++++++++ src/integrators/controllers.jl | 103 +---------- 2 files changed, 223 insertions(+), 97 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/controllers.jl b/lib/OrdinaryDiffEqBDF/src/controllers.jl index 4e6fb7675b..1247ec4cc1 100644 --- a/lib/OrdinaryDiffEqBDF/src/controllers.jl +++ b/lib/OrdinaryDiffEqBDF/src/controllers.jl @@ -3,4 +3,221 @@ end function default_controller(alg::Union{QNDF, FBDF}, args...) DummyController() +end + +# QNBDF +stepsize_controller!(integrator, alg::QNDF) = nothing + +# this stepsize and order controller is taken from +# Implementation of an Adaptive BDF2 Formula and Comparison with the MATLAB Ode15s paper +# E. Alberdi Celaya, J. J. Anza Aguirrezabala, and P. Chatzipantelidis + +function step_accept_controller!(integrator, alg::QNDF{max_order}, q) where {max_order} + #step is accepted, reset count of consecutive failed steps + integrator.cache.consfailcnt = 0 + integrator.cache.nconsteps += 1 + if iszero(integrator.EEst) + return integrator.dt * integrator.opts.qmax + else + est = integrator.EEst + estₖ₋₁ = integrator.cache.EEst1 + estₖ₊₁ = integrator.cache.EEst2 + h = integrator.dt + k = integrator.cache.order + cache = integrator.cache + prefer_const_step = integrator.cache.nconsteps < integrator.cache.order + 2 + zₛ = 1.2 # equivalent to integrator.opts.gamma + zᵤ = 0.1 + Fᵤ = 10 + expo = 1 / (k + 1) + z = zₛ * ((est)^expo) + F = inv(z) + hₙ = h + kₙ = k + if z <= zᵤ + hₖ = Fᵤ * h + else + hₖ = F * h + end + hₖ₋₁ = 0.0 + hₖ₊₁ = 0.0 + + if k > 1 + expo = 1 / k + zₖ₋₁ = 1.3 * ((estₖ₋₁)^expo) + Fₖ₋₁ = inv(zₖ₋₁) + if zₖ₋₁ <= 0.1 + hₖ₋₁ = 10 * h + elseif 1 / 10 < zₖ₋₁ <= 1.3 + hₖ₋₁ = Fₖ₋₁ * h + end + if hₖ₋₁ > hₖ + hₙ = hₖ₋₁ + kₙ = k - 1 + else + hₙ = hₖ + kₙ = k + end + else + hₙ = hₖ + kₙ = k + end + + if k < max_order + expo = 1 / (k + 2) + zₖ₊₁ = 1.4 * ((estₖ₊₁)^expo) + Fₖ₊₁ = inv(zₖ₊₁) + + if zₖ₊₁ <= 0.1 + hₖ₊₁ = 10 * h + elseif 0.1 < zₖ₊₁ <= 1.4 + hₖ₊₁ = Fₖ₊₁ * h + end + if hₖ₊₁ > hₙ + hₙ = hₖ₊₁ + kₙ = k + 1 + end + end + cache.order = kₙ + q = integrator.dt / hₙ + end + if prefer_const_step + if q < 1.2 && q > 0.6 + return integrator.dt + end + end + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + return integrator.dt + end + return integrator.dt / q +end + +function step_reject_controller!(integrator, ::QNDF) + bdf_step_reject_controller!(integrator, integrator.cache.EEst1) +end + +function step_reject_controller!(integrator, ::FBDF) + bdf_step_reject_controller!(integrator, integrator.cache.terkm1) +end + +function post_newton_controller!(integrator, alg::FBDF) + @unpack cache = integrator + if cache.order > 1 && cache.nlsolver.nfails >= 3 + cache.order -= 1 + end + integrator.dt = integrator.dt / integrator.opts.failfactor + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + nothing +end + +function choose_order!(alg::FBDF, integrator, + cache::OrdinaryDiffEqMutableCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack atmp, ts_tmp, terkm2, terkm1, terk, terkp1, terk_tmp, u_history = cache + k = cache.order + # only when the order of amount of terk follows the order of step size, and achieve enough constant step size, the order could be increased. + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * u_history[:, i - 1] + end + @.. broadcast=false terk_tmp*=abs(dt^(k - 2)) + calculate_residuals!(atmp, _vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function choose_order!(alg::FBDF, integrator, + cache::OrdinaryDiffEqConstantCache, + ::Val{max_order}) where {max_order} + @unpack t, dt, u, cache, uprev = integrator + @unpack ts_tmp, terkm2, terkm1, terk, terkp1, u_history = cache + k = cache.order + if k < max_order && integrator.cache.nconsteps >= integrator.cache.order + 2 && + ((k == 1 && terk > terkp1) || + (k == 2 && terkm1 > terk > terkp1) || + (k > 2 && terkm2 > terkm1 > terk > terkp1)) + k += 1 + terk = terkp1 + else + while !(terkm2 > terkm1 > terk > terkp1) && k > 2 + terkp1 = terk + terk = terkm1 + terkm1 = terkm2 + fd_weights = calc_finite_difference_weights(ts_tmp, t + dt, k - 2, + Val(max_order)) + terk_tmp = @.. broadcast=false fd_weights[k - 2, 1]*u + if u isa Number + for i in 2:(k - 2) + terk_tmp += fd_weights[i, k - 2] * u_history[i - 1] + end + terk_tmp *= abs(dt^(k - 2)) + else + vc = _vec(terk_tmp) + for i in 2:(k - 2) + @.. broadcast=false @views vc += fd_weights[i, k - 2] * + u_history[:, i - 1] + end + terk_tmp = reshape(vc, size(terk_tmp)) + terk_tmp *= @.. broadcast=false abs(dt^(k - 2)) + end + atmp = calculate_residuals(_vec(terk_tmp), _vec(uprev), _vec(u), + integrator.opts.abstol, integrator.opts.reltol, + integrator.opts.internalnorm, t) + terkm2 = integrator.opts.internalnorm(atmp, t) + k -= 1 + end + end + return k, terk +end + +function stepsize_controller!(integrator, + alg::FBDF{max_order}) where { + max_order, +} + @unpack cache = integrator + cache.prev_order = cache.order + k, terk = choose_order!(alg, integrator, cache, Val(max_order)) + if k != cache.order + integrator.cache.nconsteps = 0 + cache.order = k + end + if iszero(terk) + q = inv(integrator.opts.qmax) + else + q = ((2 * terk / (k + 1))^(1 / (k + 1))) + end + integrator.qold = q + q +end + +function step_accept_controller!(integrator, alg::FBDF{max_order}, + q) where {max_order} + integrator.cache.consfailcnt = 0 + if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min + q = one(q) + end + integrator.cache.nconsteps += 1 + integrator.cache.iters_from_event += 1 + return integrator.dt / q end \ No newline at end of file diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index 58adbb4dc7..d1c0a7859b 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -472,98 +472,7 @@ function step_reject_controller!(integrator, alg::JVODE) integrator.dt *= integrator.qold end -# QNBDF -stepsize_controller!(integrator, alg::QNDF) = nothing - -# this stepsize and order controller is taken from -# Implementation of an Adaptive BDF2 Formula and Comparison with the MATLAB Ode15s paper -# E. Alberdi Celaya, J. J. Anza Aguirrezabala, and P. Chatzipantelidis - -function step_accept_controller!(integrator, alg::QNDF{max_order}, q) where {max_order} - #step is accepted, reset count of consecutive failed steps - integrator.cache.consfailcnt = 0 - integrator.cache.nconsteps += 1 - if iszero(integrator.EEst) - return integrator.dt * integrator.opts.qmax - else - est = integrator.EEst - estₖ₋₁ = integrator.cache.EEst1 - estₖ₊₁ = integrator.cache.EEst2 - h = integrator.dt - k = integrator.cache.order - cache = integrator.cache - prefer_const_step = integrator.cache.nconsteps < integrator.cache.order + 2 - zₛ = 1.2 # equivalent to integrator.opts.gamma - zᵤ = 0.1 - Fᵤ = 10 - expo = 1 / (k + 1) - z = zₛ * ((est)^expo) - F = inv(z) - hₙ = h - kₙ = k - if z <= zᵤ - hₖ = Fᵤ * h - else - hₖ = F * h - end - hₖ₋₁ = 0.0 - hₖ₊₁ = 0.0 - - if k > 1 - expo = 1 / k - zₖ₋₁ = 1.3 * ((estₖ₋₁)^expo) - Fₖ₋₁ = inv(zₖ₋₁) - if zₖ₋₁ <= 0.1 - hₖ₋₁ = 10 * h - elseif 1 / 10 < zₖ₋₁ <= 1.3 - hₖ₋₁ = Fₖ₋₁ * h - end - if hₖ₋₁ > hₖ - hₙ = hₖ₋₁ - kₙ = k - 1 - else - hₙ = hₖ - kₙ = k - end - else - hₙ = hₖ - kₙ = k - end - - if k < max_order - expo = 1 / (k + 2) - zₖ₊₁ = 1.4 * ((estₖ₊₁)^expo) - Fₖ₊₁ = inv(zₖ₊₁) - - if zₖ₊₁ <= 0.1 - hₖ₊₁ = 10 * h - elseif 0.1 < zₖ₊₁ <= 1.4 - hₖ₊₁ = Fₖ₊₁ * h - end - if hₖ₊₁ > hₙ - hₙ = hₖ₊₁ - kₙ = k + 1 - end - end - cache.order = kₙ - q = integrator.dt / hₙ - end - if prefer_const_step - if q < 1.2 && q > 0.6 - return integrator.dt - end - end - if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min - return integrator.dt - end - return integrator.dt / q -end - -function step_reject_controller!(integrator, ::QNDF) - bdf_step_reject_controller!(integrator, integrator.cache.EEst1) -end - -function step_reject_controller!(integrator, ::Union{FBDF, DFBDF}) +function step_reject_controller!(integrator, ::DFBDF) bdf_step_reject_controller!(integrator, integrator.cache.terkm1) end @@ -613,7 +522,7 @@ function post_newton_controller!(integrator, alg) nothing end -function post_newton_controller!(integrator, alg::Union{FBDF, DFBDF}) +function post_newton_controller!(integrator, alg::DFBDF) @unpack cache = integrator if cache.order > 1 && cache.nlsolver.nfails >= 3 cache.order -= 1 @@ -624,7 +533,7 @@ function post_newton_controller!(integrator, alg::Union{FBDF, DFBDF}) nothing end -function choose_order!(alg::Union{FBDF, DFBDF}, integrator, +function choose_order!(alg::DFBDF, integrator, cache::OrdinaryDiffEqMutableCache, ::Val{max_order}) where {max_order} @unpack t, dt, u, cache, uprev = integrator @@ -660,7 +569,7 @@ function choose_order!(alg::Union{FBDF, DFBDF}, integrator, return k, terk end -function choose_order!(alg::Union{FBDF, DFBDF}, integrator, +function choose_order!(alg::DFBDF, integrator, cache::OrdinaryDiffEqConstantCache, ::Val{max_order}) where {max_order} @unpack t, dt, u, cache, uprev = integrator @@ -705,7 +614,7 @@ function choose_order!(alg::Union{FBDF, DFBDF}, integrator, end function stepsize_controller!(integrator, - alg::Union{FBDF{max_order}, DFBDF{max_order}}) where { + alg::DFBDF{max_order}) where { max_order, } @unpack cache = integrator @@ -724,7 +633,7 @@ function stepsize_controller!(integrator, q end -function step_accept_controller!(integrator, alg::Union{FBDF{max_order}, DFBDF{max_order}}, +function step_accept_controller!(integrator, alg::DFBDF{max_order}, q) where {max_order} integrator.cache.consfailcnt = 0 if q <= integrator.opts.qsteady_max && q >= integrator.opts.qsteady_min From 81ec410c7cd9dfb0c6800048f98dea201b06aa0b Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 09:40:33 +0530 Subject: [PATCH 053/112] FBDF --- src/OrdinaryDiffEq.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index de666cc8c4..27d1a08ea5 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -267,10 +267,6 @@ include("../lib/OrdinaryDiffEqVerner/src/OrdinaryDiffEqVerner.jl") using ..OrdinaryDiffEqVerner export Vern6, Vern7, Vern8, Vern9 -include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") -using ..OrdinaryDiffEqDefault -export DefaultODEAlgorithm - include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") using ..OrdinaryDiffEqSDIRK export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, @@ -285,6 +281,10 @@ using ..OrdinaryDiffEqBDF export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, SBDF2, SBDF3, SBDF4, MEBDF2 +include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") +using ..OrdinaryDiffEqDefault +export DefaultODEAlgorithm + import PrecompileTools PrecompileTools.@compile_workload begin From 03afe180f61465494d864985eec239632662ad10 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 09:44:19 +0530 Subject: [PATCH 054/112] AbstractController --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index c584d0b06d..ee62adada8 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -7,6 +7,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqNewtonAlgorithm, + AbstractController, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, From b63c82cbf527546e7377f4d9947398bcf1fad1ee Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Thu, 18 Jul 2024 03:02:11 -0400 Subject: [PATCH 055/112] Update src/OrdinaryDiffEq.jl --- src/OrdinaryDiffEq.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 27d1a08ea5..42a06ff623 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -269,6 +269,7 @@ export Vern6, Vern7, Vern8, Vern9 include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") using ..OrdinaryDiffEqSDIRK +import .OrdinaryDiffEqSDIRK: ImplicitEulerConstantCache export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, From b5c86fa581fefaff711c0db0685b85bd6484fa22 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 13:11:34 +0530 Subject: [PATCH 056/112] ImplicitEulerConstantCache --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 4 ++-- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index ee62adada8..347bedff08 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -8,7 +8,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqNewtonAlgorithm, AbstractController, - OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, + CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps! @@ -16,8 +16,8 @@ using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast include("algorithms.jl") include("alg_utils.jl") -include("controllers.jl") include("bdf_caches.jl") +include("controllers.jl") include("bdf_utils.jl") include("bdf_perform_step.jl") diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 05b6bcae6f..0fe65329d0 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -10,7 +10,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps! + trivial_limiter!, _ode_interpolant!, _ode_addsteps!, + ImplicitEulerConstantCache using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast include("algorithms.jl") From 9e4e24c5c1ab5ccf8627436e3957affb3713b773 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 13:30:21 +0530 Subject: [PATCH 057/112] ImplicitEulerConstantCache --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 3 ++- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 3 +-- src/OrdinaryDiffEq.jl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 347bedff08..02a93f70a3 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -11,7 +11,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps! + trivial_limiter!, _ode_interpolant!, _ode_addsteps!, + ImplicitEulerConstantCache, ImplicitEulerCache using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast include("algorithms.jl") diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 0fe65329d0..05b6bcae6f 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -10,8 +10,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps!, - ImplicitEulerConstantCache + trivial_limiter!, _ode_interpolant!, _ode_addsteps! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast include("algorithms.jl") diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 42a06ff623..0fc44f39a2 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -269,7 +269,7 @@ export Vern6, Vern7, Vern8, Vern9 include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") using ..OrdinaryDiffEqSDIRK -import .OrdinaryDiffEqSDIRK: ImplicitEulerConstantCache +import .OrdinaryDiffEqSDIRK: ImplicitEulerConstantCache, ImplicitEulerCache export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, From 9375bfbc9907d9fd5a36f78d66e58f16ab1ba90c Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 13:41:06 +0530 Subject: [PATCH 058/112] @SVector --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 02a93f70a3..04e32951f6 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -14,6 +14,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, ImplicitEulerConstantCache, ImplicitEulerCache using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast +import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA include("algorithms.jl") include("alg_utils.jl") From f30a47e8c94c11c09c7f3a495f56ee1f702ab193 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 13:57:49 +0530 Subject: [PATCH 059/112] DEFAULT_PRECS --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 05b6bcae6f..43d233343f 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -7,6 +7,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqNewtonAlgorithm, + DEFAULT_PRECS, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, From 4ac4b653cb08d8a7e87101f31d691bbd7bb1a203 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 13:58:30 +0530 Subject: [PATCH 060/112] DEFAULT_PRECS --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 04e32951f6..da8665975c 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -7,7 +7,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqNewtonAlgorithm, - AbstractController, + AbstractController, DEFAULT_PRECS, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, From fe397ddea8bf4ed455331ada2d90272437a6c370 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 14:17:42 +0530 Subject: [PATCH 061/112] DEFAULT_PRECS --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index da8665975c..ba353b7e9f 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -9,6 +9,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqNewtonAlgorithm, AbstractController, DEFAULT_PRECS, CompiledFloats, uses_uprev, + NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 43d233343f..a34f050d64 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -7,7 +7,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqNewtonAlgorithm, - DEFAULT_PRECS, + DEFAULT_PRECS, NLNewton, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, From 691ddae702eef79dd6ebb1035604ab3d0b2458e9 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 14:22:13 +0530 Subject: [PATCH 062/112] DEFAULT_PRECS --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index ba353b7e9f..391d3b5309 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -9,8 +9,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqNewtonAlgorithm, AbstractController, DEFAULT_PRECS, CompiledFloats, uses_uprev, - NLNewton, - alg_cache, _vec, _reshape, @cache, isfsal, full_cache, + NLNewton, alg_cache, _vec, _reshape, @cache, + isfsal, full_cache, build_nlsolver, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, ImplicitEulerConstantCache, ImplicitEulerCache From 9cba2559c9ff11e047b38d6151501107ab54f5bd Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 14:28:06 +0530 Subject: [PATCH 063/112] recursivefill! --- lib/OrdinaryDiffEqBDF/Project.toml | 22 ++++++++++++++++++- .../src/OrdinaryDiffEqBDF.jl | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml index 36df9f7b00..025e0fb065 100644 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -1,4 +1,24 @@ name = "OrdinaryDiffEqBDF" uuid = "6ad6398a-0878-4a85-9266-38940aa047c8" authors = ["ParamThakkar123 "] -version = "0.1.0" +version = "1.0.0" + +[deps] +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" +MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + +[extras] +DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +julia = "1.10" + +[targets] +test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] \ No newline at end of file diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 391d3b5309..cbab3b3ea1 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -14,7 +14,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, ImplicitEulerConstantCache, ImplicitEulerCache -using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast +using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA include("algorithms.jl") From d7158617c6474e67bfa8806a8ac6c7a3af8ae0aa Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 14:35:23 +0530 Subject: [PATCH 064/112] markfirststage! --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 3 ++- lib/OrdinaryDiffEqSDIRK/Project.toml | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index cbab3b3ea1..b89d0d62f3 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -13,7 +13,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, isfsal, full_cache, build_nlsolver, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, - ImplicitEulerConstantCache, ImplicitEulerCache + ImplicitEulerConstantCache, ImplicitEulerCache, + markfirststage! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 2fb44a896d..8b72c76c3e 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -9,6 +9,7 @@ TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index a34f050d64..4442d9b794 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -11,8 +11,9 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps! -using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast + markfirststage!, trivial_limiter!, _ode_interpolant!, + _ode_addsteps! +using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools include("algorithms.jl") include("alg_utils.jl") From 1320071c73b537f148d71ec187c753b75637a4c8 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 14:42:32 +0530 Subject: [PATCH 065/112] build_nlsolver --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 4442d9b794..a9fdf5d97a 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - _ode_addsteps! + _ode_addsteps!, build_nlsolver using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools include("algorithms.jl") From cadc913049b98971a40228bca2414d433d80ca18 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 15:27:38 +0530 Subject: [PATCH 066/112] SplitFunction --- lib/OrdinaryDiffEqSDIRK/Project.toml | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 8b72c76c3e..359b6a9a64 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -10,6 +10,7 @@ MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" +SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index a9fdf5d97a..af4c4eba7a 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -14,6 +14,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, markfirststage!, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, build_nlsolver using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools +using SciMLBase: SplitFunction include("algorithms.jl") include("alg_utils.jl") From 8566405bb3042b4c6ba9b926a05f69834d3b714f Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 15:34:54 +0530 Subject: [PATCH 067/112] UJacobianWrapper --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index b89d0d62f3..3b7d73bf3c 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -14,7 +14,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, ImplicitEulerConstantCache, ImplicitEulerCache, - markfirststage! + markfirststage!, UJacobianWrapper using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA From 87e6429c7ed0fdd876b66964442d9a8323d592ab Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Thu, 18 Jul 2024 07:03:39 -0400 Subject: [PATCH 068/112] Update OrdinaryDiffEqSDIRK.jl --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index af4c4eba7a..a9b6a8462c 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - _ode_addsteps!, build_nlsolver + _ode_addsteps!, build_nlsolver, nlsolve! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction @@ -31,4 +31,4 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA -end \ No newline at end of file +end From 8ffd11e614580934cbcc058b5d47cf94db70c72b Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Thu, 18 Jul 2024 07:21:51 -0400 Subject: [PATCH 069/112] Update lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index a9b6a8462c..861be1c368 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - _ode_addsteps!, build_nlsolver, nlsolve! + _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction From df49ff63b13be22be61c6cc0f2625d16b4b8f2bf Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Thu, 18 Jul 2024 07:38:48 -0400 Subject: [PATCH 070/112] Update lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 861be1c368..15838cb7af 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail + _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail, isnewton using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction From e86ebce55815d61f2260d724c6861bab52ebeb8a Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 17:22:43 +0530 Subject: [PATCH 071/112] Fixes --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 15838cb7af..e19401ccea 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,6 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, + UJacobianWrapper, _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail, isnewton using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction From 8087a80dcf30adb957ce42f22789d442ad8f9824 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 17:27:52 +0530 Subject: [PATCH 072/112] set_new_W! --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index e19401ccea..9659021eba 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - UJacobianWrapper, + UJacobianWrapper, set_new_W!, _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail, isnewton using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction From 147479ea6ad5e39b1cf6efc139d672054abe3cc5 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 17:33:40 +0530 Subject: [PATCH 073/112] Dolinsolve --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 9659021eba..5b27a008ac 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - UJacobianWrapper, set_new_W!, + UJacobianWrapper, set_new_W!, dolinsolve, _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail, isnewton using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction From 42244991bca9a1444aa50b0a775821ae29cce984 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 17:44:45 +0530 Subject: [PATCH 074/112] get_W --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 5b27a008ac..8efa474655 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - UJacobianWrapper, set_new_W!, dolinsolve, + UJacobianWrapper, set_new_W!, dolinsolve, get_W _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail, isnewton using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction From e8117ff114bc8c7f2a8bb2bd74d268f67d38dcae Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 17:52:03 +0530 Subject: [PATCH 075/112] _ode_addsteps! --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 8efa474655..c32f512126 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -12,8 +12,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, - UJacobianWrapper, set_new_W!, dolinsolve, get_W - _ode_addsteps!, build_nlsolver, nlsolve!, nlsolvefail, isnewton + UJacobianWrapper, set_new_W!, dolinsolve, get_W, + build_nlsolver, nlsolve!, nlsolvefail, isnewton using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction From 95b69eba85bd1f0efa6c9ca2424f2a1caf0300dd Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 17:53:03 +0530 Subject: [PATCH 076/112] _ode_addsteps! --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 3b7d73bf3c..4447ff4f2d 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, build_nlsolver, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, _ode_addsteps!, + trivial_limiter!, _ode_interpolant!, ImplicitEulerConstantCache, ImplicitEulerCache, markfirststage!, UJacobianWrapper using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools From dba8f81cd8143771d49689f4e4cf7a34216856f5 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 18:10:49 +0530 Subject: [PATCH 077/112] I --- lib/OrdinaryDiffEqBDF/Project.toml | 1 + lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 7 ++++--- lib/OrdinaryDiffEqSDIRK/Project.toml | 1 + lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml index 025e0fb065..045c32b646 100644 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -10,6 +10,7 @@ MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 4447ff4f2d..5e48358044 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -11,12 +11,13 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, CompiledFloats, uses_uprev, NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, build_nlsolver, - constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - trivial_limiter!, _ode_interpolant!, - ImplicitEulerConstantCache, ImplicitEulerCache, + constvalue, _unwrap_val, du_alias_or_new, + trivial_limiter!, ImplicitEulerConstantCache, + ImplicitEulerCache, markfirststage!, UJacobianWrapper using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA +using LinearAlgebra: I include("algorithms.jl") include("alg_utils.jl") diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 359b6a9a64..7d39bed0cb 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -11,6 +11,7 @@ MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [compat] julia = "1.10" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index c32f512126..610555bf02 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -16,6 +16,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, build_nlsolver, nlsolve!, nlsolvefail, isnewton using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction +using LinearAlgebra: I include("algorithms.jl") include("alg_utils.jl") From c0cb6f938d30d30c8a5b75f2343f1b20e5bba9b5 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 18:21:47 +0530 Subject: [PATCH 078/112] COEFFICIENT_MULTISTEP --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 5e48358044..78c9b7b939 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -13,7 +13,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, isfsal, full_cache, build_nlsolver, constvalue, _unwrap_val, du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, - ImplicitEulerCache, + ImplicitEulerCache, COEFFICIENT_MULTISTEP, markfirststage!, UJacobianWrapper using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 610555bf02..389d6566fd 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -13,7 +13,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, markfirststage!, trivial_limiter!, _ode_interpolant!, UJacobianWrapper, set_new_W!, dolinsolve, get_W, - build_nlsolver, nlsolve!, nlsolvefail, isnewton + build_nlsolver, nlsolve!, nlsolvefail, isnewton, + COEFFICIENT_MULTISTEP using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction using LinearAlgebra: I From 952af813d1fd5eaedd1b72479fa2d6a176a5b22c Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 18:25:53 +0530 Subject: [PATCH 079/112] nlsolve --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 78c9b7b939..dd9a9a78b7 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -11,7 +11,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, CompiledFloats, uses_uprev, NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, build_nlsolver, - constvalue, _unwrap_val, du_alias_or_new, + nlsolve!, constvalue, _unwrap_val, + du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, markfirststage!, UJacobianWrapper From a211eedb16df6ab51c073127ec06630c41aab7a1 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 18:29:39 +0530 Subject: [PATCH 080/112] error_constant --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index dd9a9a78b7..c5dc0809a3 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -12,7 +12,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, build_nlsolver, nlsolve!, constvalue, _unwrap_val, - du_alias_or_new, + du_alias_or_new, error_constant, trivial_limiter!, ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, markfirststage!, UJacobianWrapper From 82d705e6da77b6e839314c895146b420afaf6150 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 18:42:44 +0530 Subject: [PATCH 081/112] Fixes --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 7 ++++--- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index c5dc0809a3..e14b950a64 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -11,9 +11,10 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, CompiledFloats, uses_uprev, NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, build_nlsolver, - nlsolve!, constvalue, _unwrap_val, - du_alias_or_new, error_constant, - trivial_limiter!, ImplicitEulerConstantCache, + error_constant, nlsolve!, + constvalue, _unwrap_val, + du_alias_or_new, trivial_limiter!, + ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, markfirststage!, UJacobianWrapper using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 389d6566fd..ea9f724838 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -14,7 +14,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, markfirststage!, trivial_limiter!, _ode_interpolant!, UJacobianWrapper, set_new_W!, dolinsolve, get_W, build_nlsolver, nlsolve!, nlsolvefail, isnewton, - COEFFICIENT_MULTISTEP + COEFFICIENT_MULTISTEP, mul! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction using LinearAlgebra: I From 4f627a1ce84011b28fb83c97ee18d6fe1c62e82a Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 19:39:43 +0530 Subject: [PATCH 082/112] Fixes --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 4 ++-- src/OrdinaryDiffEq.jl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index e14b950a64..545707a86f 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -11,7 +11,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, CompiledFloats, uses_uprev, NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, build_nlsolver, - error_constant, nlsolve!, + nlsolve!, nlsolvefail, isnewton, constvalue, _unwrap_val, du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, @@ -23,9 +23,9 @@ using LinearAlgebra: I include("algorithms.jl") include("alg_utils.jl") +include("bdf_utils.jl") include("bdf_caches.jl") include("controllers.jl") -include("bdf_utils.jl") include("bdf_perform_step.jl") export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 0fc44f39a2..927e898b8a 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -189,7 +189,6 @@ include("perform_step/adams_bashforth_moulton_perform_step.jl") include("perform_step/nordsieck_perform_step.jl") include("perform_step/prk_perform_step.jl") include("perform_step/pdirk_perform_step.jl") -include("perform_step/dae_perform_step.jl") include("perform_step/qprk_perform_step.jl") include("dense/generic_dense.jl") @@ -286,6 +285,8 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm +include("perform_step/dae_perform_step.jl") + import PrecompileTools PrecompileTools.@compile_workload begin From 1025e3b40ccde130fb0928883fa7e9ff90498f8e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 20:33:45 +0530 Subject: [PATCH 083/112] clearing some UnDef errors --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 2 +- src/alg_utils.jl | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 545707a86f..061bbc4695 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -16,7 +16,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, - markfirststage!, UJacobianWrapper + markfirststage!, UJacobianWrapper, mul! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA using LinearAlgebra: I diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 839f0e468c..e7eaa3b8d5 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -541,6 +541,9 @@ alg_adaptive_order(alg::Exprb32) = 2 alg_adaptive_order(alg::Exprb43) = 4 alg_adaptive_order(alg::AN5) = 5 +struct DummyController <: AbstractController +end + function default_controller(alg, cache, qoldinit, _beta1 = nothing, _beta2 = nothing) if ispredictive(alg) return PredictiveController() From 5a62e583dd1894e4692b9aa6bab095255f5ab58a Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 20:43:42 +0530 Subject: [PATCH 084/112] AbstractController --- src/alg_utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alg_utils.jl b/src/alg_utils.jl index e7eaa3b8d5..34418fc1f2 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -1,5 +1,5 @@ ## SciMLBase Trait Definitions - +using OrdinaryDiffEq: AbstractController function SciMLBase.isautodifferentiable(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm, FunctionMap}) true From 780695eb1f6454f066edecf78a2c209ff51c37f8 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 20:45:35 +0530 Subject: [PATCH 085/112] AbstractController --- src/alg_utils.jl | 3 --- src/integrators/controllers.jl | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 34418fc1f2..19a26c4133 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -541,9 +541,6 @@ alg_adaptive_order(alg::Exprb32) = 2 alg_adaptive_order(alg::Exprb43) = 4 alg_adaptive_order(alg::AN5) = 5 -struct DummyController <: AbstractController -end - function default_controller(alg, cache, qoldinit, _beta1 = nothing, _beta2 = nothing) if ispredictive(alg) return PredictiveController() diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index d1c0a7859b..5ee5954838 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -57,6 +57,9 @@ the predicted step size. struct IController <: AbstractController end +struct DummyController <: AbstractController +end + @inline function stepsize_controller!(integrator, controller::IController, alg) @unpack qmin, qmax, gamma = integrator.opts EEst = DiffEqBase.value(integrator.EEst) From 8f434ec6ca56620e093574a5118a824d0f4d4260 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Thu, 18 Jul 2024 20:49:54 +0530 Subject: [PATCH 086/112] AbstractController --- src/alg_utils.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 19a26c4133..332fed9b6f 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -1,5 +1,4 @@ ## SciMLBase Trait Definitions -using OrdinaryDiffEq: AbstractController function SciMLBase.isautodifferentiable(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm, FunctionMap}) true From aef0448579889fa4a66cf47ccf63bcc71eed4335 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Fri, 19 Jul 2024 18:10:56 +0530 Subject: [PATCH 087/112] DIRK --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 061bbc4695..f53c0e98f8 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -13,6 +13,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, isfsal, full_cache, build_nlsolver, nlsolve!, nlsolvefail, isnewton, constvalue, _unwrap_val, + DIRK, du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, From c4534bf9fe2465578886c49e2d82c2d16efef0f2 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 19 Jul 2024 21:06:17 -0400 Subject: [PATCH 088/112] Update OrdinaryDiffEq.jl --- src/OrdinaryDiffEq.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 927e898b8a..33a55af202 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -285,6 +285,7 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm +using ..OrdinaryDiffEqBDF: reinitFBDF! include("perform_step/dae_perform_step.jl") import PrecompileTools From 7fb5eaf02ad9e51e9cba68d9fdf4141c35cedbcc Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 10:23:39 +0530 Subject: [PATCH 089/112] error_constant --- lib/OrdinaryDiffEqBDF/Project.toml | 1 + src/OrdinaryDiffEq.jl | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml index 045c32b646..dd1b53ea4c 100644 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -11,6 +11,7 @@ MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index b76e8644d3..dcc151467f 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -138,12 +138,6 @@ include("composite_algs.jl") include("alg_utils.jl") -include("nlsolve/type.jl") -include("nlsolve/utils.jl") -include("nlsolve/nlsolve.jl") -include("nlsolve/functional.jl") -include("nlsolve/newton.jl") - include("generic_rosenbrock.jl") include("caches/basic_caches.jl") @@ -285,9 +279,15 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm -using ..OrdinaryDiffEqBDF: reinitFBDF! +using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant include("perform_step/dae_perform_step.jl") +include("nlsolve/type.jl") +include("nlsolve/utils.jl") +include("nlsolve/nlsolve.jl") +include("nlsolve/functional.jl") +include("nlsolve/newton.jl") + import PrecompileTools PrecompileTools.@compile_workload begin From fa9e7e3e2c0ac35eaf24933bc1cd3f6aa5a384f4 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 10:28:24 +0530 Subject: [PATCH 090/112] error_constant --- src/OrdinaryDiffEq.jl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index dcc151467f..dbd85fedfb 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -112,6 +112,8 @@ using MacroTools, Adapt using SciMLStructures: canonicalize, Tunable, isscimlstructure +using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant + const CompiledFloats = Union{Float32, Float64, ForwardDiff.Dual{ ForwardDiff.Tag{T, W}, @@ -138,6 +140,12 @@ include("composite_algs.jl") include("alg_utils.jl") +include("nlsolve/type.jl") +include("nlsolve/utils.jl") +include("nlsolve/nlsolve.jl") +include("nlsolve/functional.jl") +include("nlsolve/newton.jl") + include("generic_rosenbrock.jl") include("caches/basic_caches.jl") @@ -279,15 +287,8 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm -using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant include("perform_step/dae_perform_step.jl") -include("nlsolve/type.jl") -include("nlsolve/utils.jl") -include("nlsolve/nlsolve.jl") -include("nlsolve/functional.jl") -include("nlsolve/newton.jl") - import PrecompileTools PrecompileTools.@compile_workload begin From 299e32814acd4fa7590f5a6a8cc1fa7f491a42bc Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 10:34:44 +0530 Subject: [PATCH 091/112] error_constant --- src/OrdinaryDiffEq.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index dbd85fedfb..04d0f9016a 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -112,8 +112,6 @@ using MacroTools, Adapt using SciMLStructures: canonicalize, Tunable, isscimlstructure -using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant - const CompiledFloats = Union{Float32, Float64, ForwardDiff.Dual{ ForwardDiff.Tag{T, W}, @@ -142,7 +140,6 @@ include("alg_utils.jl") include("nlsolve/type.jl") include("nlsolve/utils.jl") -include("nlsolve/nlsolve.jl") include("nlsolve/functional.jl") include("nlsolve/newton.jl") @@ -287,6 +284,8 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm +using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant +include("nlsolve/nlsolve.jl") include("perform_step/dae_perform_step.jl") import PrecompileTools From 47c0cde6952fcd7ecb84543a27b61d563a27f55a Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 10:40:02 +0530 Subject: [PATCH 092/112] error_constant --- src/OrdinaryDiffEq.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 04d0f9016a..dae7943055 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -140,8 +140,8 @@ include("alg_utils.jl") include("nlsolve/type.jl") include("nlsolve/utils.jl") +include("nlsolve/nlsolve.jl") include("nlsolve/functional.jl") -include("nlsolve/newton.jl") include("generic_rosenbrock.jl") @@ -285,7 +285,7 @@ using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant -include("nlsolve/nlsolve.jl") +include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") import PrecompileTools From 5db0b860e76187acae0cc91a2f6aba1c28659e74 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 10:43:53 +0530 Subject: [PATCH 093/112] ArrayInterface --- lib/OrdinaryDiffEqBDF/Project.toml | 1 + lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml index dd1b53ea4c..4c0e23c6f0 100644 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -12,6 +12,7 @@ FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" +ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index f53c0e98f8..e366f950b3 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -21,6 +21,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA using LinearAlgebra: I +using ArrayInterface include("algorithms.jl") include("alg_utils.jl") From 58ff0719b88ceb7623ccbe2e73cf22f7fbabdc18 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 10:55:40 +0530 Subject: [PATCH 094/112] estimate_terk! --- src/OrdinaryDiffEq.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index dae7943055..032dc2e50f 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -284,7 +284,7 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm -using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant +using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk! include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") From b314617bab9690090d0f49907474e0a33bbd931e Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 11:07:37 +0530 Subject: [PATCH 095/112] calc_Lagrange_interp! --- src/OrdinaryDiffEq.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 032dc2e50f..3a74e7112e 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -284,7 +284,7 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm -using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk! +using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp! include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") From 362d44d26b756df002b188f15498a3a56df37eb7 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 11:44:11 +0530 Subject: [PATCH 096/112] changes --- src/OrdinaryDiffEq.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 3a74e7112e..29a7cd4dbc 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -166,7 +166,6 @@ include("tableaus/firk_tableaus.jl") include("tableaus/qprk_tableaus.jl") include("integrators/type.jl") -include("integrators/controllers.jl") include("integrators/integrator_utils.jl") include("integrators/integrator_interface.jl") @@ -285,7 +284,9 @@ using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp! + calc_finite_difference_weights include("nlsolve/newton.jl") +include("integrators/controllers.jl") include("perform_step/dae_perform_step.jl") import PrecompileTools From a1529c295f69bece6d41dac9bc2cda97bfaf43f3 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 11:47:22 +0530 Subject: [PATCH 097/112] changes --- src/OrdinaryDiffEq.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 29a7cd4dbc..0ab6aa564c 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -166,6 +166,7 @@ include("tableaus/firk_tableaus.jl") include("tableaus/qprk_tableaus.jl") include("integrators/type.jl") +include("integrators/controllers.jl") include("integrators/integrator_utils.jl") include("integrators/integrator_interface.jl") @@ -286,7 +287,6 @@ export DefaultODEAlgorithm using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp! calc_finite_difference_weights include("nlsolve/newton.jl") -include("integrators/controllers.jl") include("perform_step/dae_perform_step.jl") import PrecompileTools From baa82141ff31c5049b06a5d633bc6ffdb3e64379 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 11:49:29 +0530 Subject: [PATCH 098/112] changes --- src/OrdinaryDiffEq.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 0ab6aa564c..e7c283ba34 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -284,7 +284,7 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm -using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp! +using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp!, calc_finite_difference_weights include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") From 69bbc99eb379952031d8a2899866e39eccf1439b Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 12:07:10 +0530 Subject: [PATCH 099/112] estimate_terk --- src/OrdinaryDiffEq.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index e7c283ba34..7dcc8f83f0 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -285,7 +285,7 @@ using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp!, - calc_finite_difference_weights + calc_finite_difference_weights, estimate_terk include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") From 11fa63d58666370f2f3fa436314090791d465ab3 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 12:57:51 +0530 Subject: [PATCH 100/112] calc_Lagrange_interp --- src/OrdinaryDiffEq.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 7dcc8f83f0..aad93b9421 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -285,7 +285,7 @@ using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp!, - calc_finite_difference_weights, estimate_terk + calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") From 8d15804d1faaa424c0e3092e556d5d59da1074f1 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 13:23:26 +0530 Subject: [PATCH 101/112] set_new_W! --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index e366f950b3..9094fd4217 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -13,7 +13,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, isfsal, full_cache, build_nlsolver, nlsolve!, nlsolvefail, isnewton, constvalue, _unwrap_val, - DIRK, + DIRK, set_new_W!, du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, From 58cd37d7ca69868037052c31af5ea5f9b8a1be46 Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 13:27:30 +0530 Subject: [PATCH 102/112] IMEXEuler --- lib/OrdinaryDiffEqBDF/src/algorithms.jl | 57 ----------------------- lib/OrdinaryDiffEqSDIRK/src/algorithms.jl | 57 +++++++++++++++++++++++ src/OrdinaryDiffEq.jl | 14 +++--- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 4862ee2daf..bcdd80971c 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -84,63 +84,6 @@ function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val ark) end -""" - IMEXEuler(;kwargs...) - -The one-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -When applied to a `SplitODEProblem` of the form - -``` -u'(t) = f1(u) + f2(u) -``` - -The default `IMEXEuler()` method uses an update of the form - -``` -unew = uold + dt * (f1(unew) + f2(uold)) -``` - -See also `SBDF`, `IMEXEulerARK`. -""" -IMEXEuler(; kwargs...) = SBDF(1; kwargs...) - -""" - IMEXEulerARK(;kwargs...) - -The one-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -When applied to a `SplitODEProblem` of the form - -``` -u'(t) = f1(u) + f2(u) -``` - -A classical additive Runge-Kutta method in the sense of -[Araújo, Murua, Sanz-Serna (1997)](https://doi.org/10.1137/S0036142995292128) -consisting of the implicit and the explicit Euler method given by - -``` -y1 = uold + dt * f1(y1) -unew = uold + dt * (f1(unew) + f2(y1)) -``` - -See also `SBDF`, `IMEXEuler`. -""" -IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) - """ SBDF2(;kwargs...) diff --git a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl index 2cb31058e5..a309de41ea 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl @@ -130,6 +130,63 @@ end TruncatedStacktraces.@truncate_stacktrace TRBDF2 +""" + IMEXEuler(;kwargs...) + +The one-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +When applied to a `SplitODEProblem` of the form + +``` +u'(t) = f1(u) + f2(u) +``` + +The default `IMEXEuler()` method uses an update of the form + +``` +unew = uold + dt * (f1(unew) + f2(uold)) +``` + +See also `SBDF`, `IMEXEulerARK`. +""" +IMEXEuler(; kwargs...) = SBDF(1; kwargs...) + +""" + IMEXEulerARK(;kwargs...) + +The one-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +When applied to a `SplitODEProblem` of the form + +``` +u'(t) = f1(u) + f2(u) +``` + +A classical additive Runge-Kutta method in the sense of +[Araújo, Murua, Sanz-Serna (1997)](https://doi.org/10.1137/S0036142995292128) +consisting of the implicit and the explicit Euler method given by + +``` +y1 = uold + dt * f1(y1) +unew = uold + dt * (f1(unew) + f2(y1)) +``` + +See also `SBDF`, `IMEXEuler`. +""" +IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) + """ @article{hindmarsh2005sundials, title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index aad93b9421..0c083b67ac 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -265,6 +265,11 @@ include("../lib/OrdinaryDiffEqVerner/src/OrdinaryDiffEqVerner.jl") using ..OrdinaryDiffEqVerner export Vern6, Vern7, Vern8, Vern9 +include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") +using ..OrdinaryDiffEqBDF +export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, + SBDF2, SBDF3, SBDF4, MEBDF2 + include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") using ..OrdinaryDiffEqSDIRK import .OrdinaryDiffEqSDIRK: ImplicitEulerConstantCache, ImplicitEulerCache @@ -272,14 +277,9 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, - SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, IMEXEuler, IMEXEulerARK, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA -include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") -using ..OrdinaryDiffEqBDF -export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2 - include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm @@ -452,7 +452,7 @@ export VCAB3, VCAB4, VCAB5, VCABM3, VCABM4, VCABM5 export VCABM -export IMEXEuler, IMEXEulerARK, CNAB2, CNLF2 +export CNAB2, CNLF2 export AN5, JVODE, JVODE_Adams, JVODE_BDF From 38bf31f25bec17e9f00f01a6ca4309df9266ea7b Mon Sep 17 00:00:00 2001 From: ParamThakkar123 Date: Sat, 20 Jul 2024 13:30:20 +0530 Subject: [PATCH 103/112] IMEXEuler --- src/OrdinaryDiffEq.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 0c083b67ac..5b6e3d562e 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -265,11 +265,6 @@ include("../lib/OrdinaryDiffEqVerner/src/OrdinaryDiffEqVerner.jl") using ..OrdinaryDiffEqVerner export Vern6, Vern7, Vern8, Vern9 -include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") -using ..OrdinaryDiffEqBDF -export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2 - include("../lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl") using ..OrdinaryDiffEqSDIRK import .OrdinaryDiffEqSDIRK: ImplicitEulerConstantCache, ImplicitEulerCache @@ -280,6 +275,11 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, IMEXEuler, IMEXEulerARK, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA +include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") +using ..OrdinaryDiffEqBDF +export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, + SBDF2, SBDF3, SBDF4, MEBDF2 + include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm From d0e4048e5a66563b805d0fa831ee7c05b9f3b1e4 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 14:56:20 -0400 Subject: [PATCH 104/112] Update lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index ea9f724838..fda3a32b73 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -31,7 +31,7 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, - SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, IMEXEuler, IMEXEulerARK, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA end From 52a57d0411a890f778ba3aa3f7fb957b4d6761d8 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 14:59:19 -0400 Subject: [PATCH 105/112] Update lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 9094fd4217..384fa2cfb2 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -17,7 +17,9 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, du_alias_or_new, trivial_limiter!, ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, - markfirststage!, UJacobianWrapper, mul! + markfirststage!, UJacobianWrapper, mul!, + issplit, qsteady_min_default, qsteady_max_default, + get_current_alg_order, get_current_adaptive_order using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA using LinearAlgebra: I From 04faf8a142043508348bd140ee19941a50496953 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 15:08:56 -0400 Subject: [PATCH 106/112] Update lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl --- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index fda3a32b73..41c0236a15 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -14,7 +14,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, markfirststage!, trivial_limiter!, _ode_interpolant!, UJacobianWrapper, set_new_W!, dolinsolve, get_W, build_nlsolver, nlsolve!, nlsolvefail, isnewton, - COEFFICIENT_MULTISTEP, mul! + COEFFICIENT_MULTISTEP, mul!, isesdirk, issplit, + ssp_coefficient using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction using LinearAlgebra: I From 67485acae81930064e8e0cba2b8e9ca0471e283f Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 15:40:55 -0400 Subject: [PATCH 107/112] Update lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 384fa2cfb2..afc75f8021 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -19,7 +19,9 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, ImplicitEulerCache, COEFFICIENT_MULTISTEP, markfirststage!, UJacobianWrapper, mul!, issplit, qsteady_min_default, qsteady_max_default, - get_current_alg_order, get_current_adaptive_order + get_current_alg_order, get_current_adaptive_order, + default_controller, stepsize_controller!, step_accept_controller!, + step_reject_controller!, post_newton_controller! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA using LinearAlgebra: I From e152e207ec9aef58daadc195344121850e2a49af Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 16:27:15 -0400 Subject: [PATCH 108/112] move BDF controller --- lib/OrdinaryDiffEqBDF/src/controllers.jl | 41 ++++++++++++++++++++++++ src/OrdinaryDiffEq.jl | 3 +- src/integrators/controllers.jl | 41 ------------------------ 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/controllers.jl b/lib/OrdinaryDiffEqBDF/src/controllers.jl index 1247ec4cc1..7c99952ed9 100644 --- a/lib/OrdinaryDiffEqBDF/src/controllers.jl +++ b/lib/OrdinaryDiffEqBDF/src/controllers.jl @@ -100,6 +100,47 @@ function step_reject_controller!(integrator, ::FBDF) bdf_step_reject_controller!(integrator, integrator.cache.terkm1) end +function bdf_step_reject_controller!(integrator, EEst1) + k = integrator.cache.order + h = integrator.dt + integrator.cache.consfailcnt += 1 + integrator.cache.nconsteps = 0 + if integrator.cache.consfailcnt > 1 + h = h / 2 + end + zₛ = 1.2 # equivalent to integrator.opts.gamma + expo = 1 / (k + 1) + z = zₛ * ((integrator.EEst)^expo) + F = inv(z) + if z <= 10 + hₖ = F * h + else # z > 10 + hₖ = 0.1 * h + end + hₙ = hₖ + kₙ = k + if k > 1 + expo = 1 / k + zₖ₋₁ = 1.3 * (EEst1^expo) + Fₖ₋₁ = inv(zₖ₋₁) + if zₖ₋₁ <= 10 + hₖ₋₁ = Fₖ₋₁ * h + elseif zₖ₋₁ > 10 + hₖ₋₁ = 0.1 * h + end + if integrator.cache.consfailcnt > 2 || hₖ₋₁ > hₖ + hₙ = min(h, hₖ₋₁) + kₙ = k - 1 + end + end + # Restart BDf (clear history) when we failed repeatedly + if kₙ == 1 && integrator.cache.consfailcnt > 3 + u_modified!(integrator, true) + end + integrator.dt = hₙ + integrator.cache.order = kₙ +end + function post_newton_controller!(integrator, alg::FBDF) @unpack cache = integrator if cache.order > 1 && cache.nlsolver.nfails >= 3 diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 5b6e3d562e..b191931110 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -285,7 +285,8 @@ using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp!, - calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp + calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp, + bdf_step_reject_controller! include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") diff --git a/src/integrators/controllers.jl b/src/integrators/controllers.jl index db77a6c936..69169566c3 100644 --- a/src/integrators/controllers.jl +++ b/src/integrators/controllers.jl @@ -479,47 +479,6 @@ function step_reject_controller!(integrator, ::DFBDF) bdf_step_reject_controller!(integrator, integrator.cache.terkm1) end -function bdf_step_reject_controller!(integrator, EEst1) - k = integrator.cache.order - h = integrator.dt - integrator.cache.consfailcnt += 1 - integrator.cache.nconsteps = 0 - if integrator.cache.consfailcnt > 1 - h = h / 2 - end - zₛ = 1.2 # equivalent to integrator.opts.gamma - expo = 1 / (k + 1) - z = zₛ * ((integrator.EEst)^expo) - F = inv(z) - if z <= 10 - hₖ = F * h - else # z > 10 - hₖ = 0.1 * h - end - hₙ = hₖ - kₙ = k - if k > 1 - expo = 1 / k - zₖ₋₁ = 1.3 * (EEst1^expo) - Fₖ₋₁ = inv(zₖ₋₁) - if zₖ₋₁ <= 10 - hₖ₋₁ = Fₖ₋₁ * h - elseif zₖ₋₁ > 10 - hₖ₋₁ = 0.1 * h - end - if integrator.cache.consfailcnt > 2 || hₖ₋₁ > hₖ - hₙ = min(h, hₖ₋₁) - kₙ = k - 1 - end - end - # Restart BDf (clear history) when we failed repeatedly - if kₙ == 1 && integrator.cache.consfailcnt > 3 - u_modified!(integrator, true) - end - integrator.dt = hₙ - integrator.cache.order = kₙ -end - function post_newton_controller!(integrator, alg) integrator.dt = integrator.dt / integrator.opts.failfactor nothing From dff53aad1c4c48e302292253d149b8246232e8b0 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 16:29:36 -0400 Subject: [PATCH 109/112] format --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 10 +++++----- lib/OrdinaryDiffEqBDF/src/alg_utils.jl | 2 +- lib/OrdinaryDiffEqBDF/src/algorithms.jl | 2 +- lib/OrdinaryDiffEqBDF/src/bdf_caches.jl | 2 +- lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl | 2 +- lib/OrdinaryDiffEqBDF/src/bdf_utils.jl | 2 +- lib/OrdinaryDiffEqBDF/src/controllers.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/algorithms.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl | 2 +- .../src/kencarp_kvaerno_perform_step.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl | 2 +- src/OrdinaryDiffEq.jl | 6 ++++-- src/alg_utils.jl | 3 +-- 17 files changed, 24 insertions(+), 23 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index afc75f8021..c9b9282ce5 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -9,18 +9,18 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqNewtonAlgorithm, AbstractController, DEFAULT_PRECS, CompiledFloats, uses_uprev, - NLNewton, alg_cache, _vec, _reshape, @cache, + NLNewton, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, build_nlsolver, nlsolve!, nlsolvefail, isnewton, - constvalue, _unwrap_val, + constvalue, _unwrap_val, DIRK, set_new_W!, - du_alias_or_new, trivial_limiter!, - ImplicitEulerConstantCache, + du_alias_or_new, trivial_limiter!, + ImplicitEulerConstantCache, ImplicitEulerCache, COEFFICIENT_MULTISTEP, markfirststage!, UJacobianWrapper, mul!, issplit, qsteady_min_default, qsteady_max_default, get_current_alg_order, get_current_adaptive_order, - default_controller, stepsize_controller!, step_accept_controller!, + default_controller, stepsize_controller!, step_accept_controller!, step_reject_controller!, post_newton_controller! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA diff --git a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl index d5c93df0c1..aea50d0df0 100644 --- a/lib/OrdinaryDiffEqBDF/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqBDF/src/alg_utils.jl @@ -23,4 +23,4 @@ get_current_alg_order(alg::QNDF, cache) = cache.order get_current_alg_order(alg::FBDF, cache) = cache.order get_current_adaptive_order(alg::QNDF, cache) = cache.order -get_current_adaptive_order(alg::FBDF, cache) = cache.order \ No newline at end of file +get_current_adaptive_order(alg::FBDF, cache) = cache.order diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index bcdd80971c..640466a84f 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -330,4 +330,4 @@ QBDF: Multistep Method An alias of `QNDF` with κ=0. """ -QBDF(; kwargs...) = QNDF(; kappa = tuple(0 // 1, 0 // 1, 0 // 1, 0 // 1, 0 // 1), kwargs...) \ No newline at end of file +QBDF(; kwargs...) = QNDF(; kappa = tuple(0 // 1, 0 // 1, 0 // 1, 0 // 1, 0 // 1), kwargs...) diff --git a/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl b/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl index f15cb8006b..78a64c7c7b 100644 --- a/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl +++ b/lib/OrdinaryDiffEqBDF/src/bdf_caches.jl @@ -655,4 +655,4 @@ function alg_cache(alg::FBDF{MO}, u, rate_prototype, ::Type{uEltypeNoUnits}, u_corrector, u₀, bdf_coeffs, Val(5), nconsteps, consfailcnt, tmp, atmp, terkm2, terkm1, terk, terkp1, terk_tmp, terkp1_tmp, r, weights, equi_ts, iters_from_event, alg.step_limiter!) -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl b/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl index 082d4faa03..e52686c8cc 100644 --- a/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl +++ b/lib/OrdinaryDiffEqBDF/src/bdf_perform_step.jl @@ -1342,4 +1342,4 @@ function perform_step!(integrator, cache::FBDFCache{max_order}, f(integrator.fsallast, u, p, tdt) integrator.stats.nf += 1 -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqBDF/src/bdf_utils.jl b/lib/OrdinaryDiffEqBDF/src/bdf_utils.jl index a89682ba5b..29c0e696b0 100644 --- a/lib/OrdinaryDiffEqBDF/src/bdf_utils.jl +++ b/lib/OrdinaryDiffEqBDF/src/bdf_utils.jl @@ -272,4 +272,4 @@ function estimate_terk(integrator, cache, k, ::Val{max_order}, u) where {max_ord terk *= abs(dt^(k - 1)) end return terk -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqBDF/src/controllers.jl b/lib/OrdinaryDiffEqBDF/src/controllers.jl index 7c99952ed9..4c1e8b9274 100644 --- a/lib/OrdinaryDiffEqBDF/src/controllers.jl +++ b/lib/OrdinaryDiffEqBDF/src/controllers.jl @@ -261,4 +261,4 @@ function step_accept_controller!(integrator, alg::FBDF{max_order}, integrator.cache.nconsteps += 1 integrator.cache.iters_from_event += 1 return integrator.dt / q -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index 41c0236a15..c4e1b14b9c 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -11,7 +11,7 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, alg_cache, _vec, _reshape, @cache, isfsal, full_cache, constvalue, _unwrap_val, du_alias_or_new, _ode_interpolant, - markfirststage!, trivial_limiter!, _ode_interpolant!, + markfirststage!, trivial_limiter!, _ode_interpolant!, UJacobianWrapper, set_new_W!, dolinsolve, get_W, build_nlsolver, nlsolve!, nlsolvefail, isnewton, COEFFICIENT_MULTISTEP, mul!, isesdirk, issplit, diff --git a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl index 714bf60ded..a4ac5fee51 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/alg_utils.jl @@ -52,4 +52,4 @@ issplit(alg::KenCarp4) = true issplit(alg::KenCarp47) = true issplit(alg::KenCarp5) = true issplit(alg::KenCarp58) = true -issplit(alg::CFNLIRK3) = true \ No newline at end of file +issplit(alg::CFNLIRK3) = true diff --git a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl index a309de41ea..5d92792e8d 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl @@ -916,4 +916,4 @@ function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, controller) -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl index 0af6130b8b..e239a42f10 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_caches.jl @@ -639,4 +639,4 @@ function alg_cache(alg::KenCarp58, u, rate_prototype, ::Type{uEltypeNoUnits}, KenCarp58Cache(u, uprev, fsalfirst, z₁, z₂, z₃, z₄, z₅, z₆, z₇, z₈, k1, k2, k3, k4, k5, k6, k7, k8, atmp, nlsolver, tab) -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl index bd43f4faea..1b3d6f1a7b 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/kencarp_kvaerno_perform_step.jl @@ -2662,4 +2662,4 @@ end else @.. broadcast=false integrator.fsallast=z₈ / dt end -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl index eafca44bd1..5664341626 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_caches.jl @@ -995,4 +995,4 @@ function alg_cache(alg::ESDIRK659L2SA, u, rate_prototype, ::Type{uEltypeNoUnits} nlsolver = build_nlsolver(alg, u, uprev, p, t, dt, f, rate_prototype, uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits, γ, c, Val(false)) ESDIRK659L2SAConstantCache(nlsolver, tab) -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl index 84db426936..d94bf0085f 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_perform_step.jl @@ -3151,4 +3151,4 @@ end @.. broadcast=false integrator.fsallast=z₉ / dt return -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl b/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl index f008557fda..ed95cef957 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/sdirk_tableaus.jl @@ -2773,4 +2773,4 @@ function KenCarp58Tableau(T, T2) ea64, ea65, ea71, ea72, ea73, ea74, ea75, ea76, ea81, ea82, ea83, ea84, ea85, ea86, ea87, eb3, eb4, eb5, eb6, eb7, eb8, ebtilde3, ebtilde4, ebtilde5, ebtilde6, ebtilde7, ebtilde8) -end \ No newline at end of file +end diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index b191931110..97985c02c1 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -284,8 +284,10 @@ include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault export DefaultODEAlgorithm -using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, calc_Lagrange_interp!, - calc_finite_difference_weights, estimate_terk, calc_Lagrange_interp, +using ..OrdinaryDiffEqBDF: reinitFBDF!, error_constant, estimate_terk!, + calc_Lagrange_interp!, + calc_finite_difference_weights, estimate_terk, + calc_Lagrange_interp, bdf_step_reject_controller! include("nlsolve/newton.jl") include("perform_step/dae_perform_step.jl") diff --git a/src/alg_utils.jl b/src/alg_utils.jl index 3df6ea7d74..77bf1df0f4 100644 --- a/src/alg_utils.jl +++ b/src/alg_utils.jl @@ -507,7 +507,6 @@ alg_order(alg::CNLF2) = 2 alg_order(alg::AN5) = 5 alg_order(alg::JVODE) = 1 #dummy value - alg_order(alg::PDIRK44) = 4 alg_order(alg::DImplicitEuler) = 1 @@ -698,4 +697,4 @@ isesdirk(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::Union{OrdinaryDiffEqAlgorithm, DAEAlgorithm}) = false is_mass_matrix_alg(alg::CompositeAlgorithm) = all(is_mass_matrix_alg, alg.algs) is_mass_matrix_alg(alg::RosenbrockAlgorithm) = true -is_mass_matrix_alg(alg::NewtonAlgorithm) = !isesdirk(alg) \ No newline at end of file +is_mass_matrix_alg(alg::NewtonAlgorithm) = !isesdirk(alg) From 3afb3ce015c7a2a486e9f2b236c2be3c9fde93e6 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 16:51:53 -0400 Subject: [PATCH 110/112] add missing import --- lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index c9b9282ce5..c76d75be39 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -21,7 +21,8 @@ import OrdinaryDiffEq: alg_order, calculate_residuals!, issplit, qsteady_min_default, qsteady_max_default, get_current_alg_order, get_current_adaptive_order, default_controller, stepsize_controller!, step_accept_controller!, - step_reject_controller!, post_newton_controller! + step_reject_controller!, post_newton_controller!, + u_modified! using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA using LinearAlgebra: I From 3ad80a208648b690d4179accad7729bf874ff3cd Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 20 Jul 2024 16:53:40 -0400 Subject: [PATCH 111/112] Move IMEXEuler and IMEXEulerARK --- .../src/OrdinaryDiffEqBDF.jl | 2 +- lib/OrdinaryDiffEqBDF/src/algorithms.jl | 57 +++++++++++++++++++ .../src/OrdinaryDiffEqSDIRK.jl | 2 +- lib/OrdinaryDiffEqSDIRK/src/algorithms.jl | 57 ------------------- src/OrdinaryDiffEq.jl | 4 +- 5 files changed, 61 insertions(+), 61 deletions(-) diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index c76d75be39..2080050161 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -36,6 +36,6 @@ include("controllers.jl") include("bdf_perform_step.jl") export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2 + SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK end diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 640466a84f..0a91dce0b6 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -331,3 +331,60 @@ QBDF: Multistep Method An alias of `QNDF` with κ=0. """ QBDF(; kwargs...) = QNDF(; kappa = tuple(0 // 1, 0 // 1, 0 // 1, 0 // 1, 0 // 1), kwargs...) + +""" + IMEXEuler(;kwargs...) + +The one-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +When applied to a `SplitODEProblem` of the form + +``` +u'(t) = f1(u) + f2(u) +``` + +The default `IMEXEuler()` method uses an update of the form + +``` +unew = uold + dt * (f1(unew) + f2(uold)) +``` + +See also `SBDF`, `IMEXEulerARK`. +""" +IMEXEuler(; kwargs...) = SBDF(1; kwargs...) + +""" + IMEXEulerARK(;kwargs...) + +The one-step version of the IMEX multistep methods of + + - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. + Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. + Society for Industrial and Applied Mathematics. + Journal on Numerical Analysis, 32(3), pp 797-823, 1995. + doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) + +When applied to a `SplitODEProblem` of the form + +``` +u'(t) = f1(u) + f2(u) +``` + +A classical additive Runge-Kutta method in the sense of +[Araújo, Murua, Sanz-Serna (1997)](https://doi.org/10.1137/S0036142995292128) +consisting of the implicit and the explicit Euler method given by + +``` +y1 = uold + dt * f1(y1) +unew = uold + dt * (f1(unew) + f2(y1)) +``` + +See also `SBDF`, `IMEXEuler`. +""" +IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index c4e1b14b9c..30c0bf3b7b 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -32,7 +32,7 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, - SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, IMEXEuler, IMEXEulerARK, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA end diff --git a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl index 5d92792e8d..01f796f650 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl @@ -130,63 +130,6 @@ end TruncatedStacktraces.@truncate_stacktrace TRBDF2 -""" - IMEXEuler(;kwargs...) - -The one-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -When applied to a `SplitODEProblem` of the form - -``` -u'(t) = f1(u) + f2(u) -``` - -The default `IMEXEuler()` method uses an update of the form - -``` -unew = uold + dt * (f1(unew) + f2(uold)) -``` - -See also `SBDF`, `IMEXEulerARK`. -""" -IMEXEuler(; kwargs...) = SBDF(1; kwargs...) - -""" - IMEXEulerARK(;kwargs...) - -The one-step version of the IMEX multistep methods of - - - Uri M. Ascher, Steven J. Ruuth, Brian T. R. Wetton. - Implicit-Explicit Methods for Time-Dependent Partial Differential Equations. - Society for Industrial and Applied Mathematics. - Journal on Numerical Analysis, 32(3), pp 797-823, 1995. - doi: [https://doi.org/10.1137/0732037](https://doi.org/10.1137/0732037) - -When applied to a `SplitODEProblem` of the form - -``` -u'(t) = f1(u) + f2(u) -``` - -A classical additive Runge-Kutta method in the sense of -[Araújo, Murua, Sanz-Serna (1997)](https://doi.org/10.1137/S0036142995292128) -consisting of the implicit and the explicit Euler method given by - -``` -y1 = uold + dt * f1(y1) -unew = uold + dt * (f1(unew) + f2(y1)) -``` - -See also `SBDF`, `IMEXEuler`. -""" -IMEXEulerARK(; kwargs...) = SBDF(1; ark = true, kwargs...) - """ @article{hindmarsh2005sundials, title={{SUNDIALS}: Suite of nonlinear and differential/algebraic equation solvers}, diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index 97985c02c1..6214e87808 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -272,13 +272,13 @@ export ImplicitEuler, ImplicitMidpoint, Trapezoid, TRBDF2, SDIRK2, SDIRK22, Kvaerno3, KenCarp3, Cash4, Hairer4, Hairer42, SSPSDIRK2, Kvaerno4, Kvaerno5, KenCarp4, KenCarp47, KenCarp5, KenCarp58, ESDIRK54I8L2SA, SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, Kvaerno5, KenCarp4, KenCarp5, - SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, IMEXEuler, IMEXEulerARK, + SFSDIRK4, SFSDIRK5, CFNLIRK3, SFSDIRK6, SFSDIRK7, SFSDIRK8, ESDIRK436L2SA2, ESDIRK437L2SA, ESDIRK547L2SA2, ESDIRK659L2SA include("../lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl") using ..OrdinaryDiffEqBDF export ABDF2, QNDF1, QBDF1, QNDF2, QBDF2, QNDF, QBDF, FBDF, - SBDF2, SBDF3, SBDF4, MEBDF2 + SBDF2, SBDF3, SBDF4, MEBDF2, IMEXEuler, IMEXEulerARK include("../lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl") using ..OrdinaryDiffEqDefault From ba512f0e0756222c61807e749ae729c77e568e96 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sun, 21 Jul 2024 15:19:39 -0400 Subject: [PATCH 112/112] Remove Rodas interpolation error allocation --- src/perform_step/rosenbrock_perform_step.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/perform_step/rosenbrock_perform_step.jl b/src/perform_step/rosenbrock_perform_step.jl index 8cd2ffd1f3..67db01d3fc 100644 --- a/src/perform_step/rosenbrock_perform_step.jl +++ b/src/perform_step/rosenbrock_perform_step.jl @@ -1947,7 +1947,7 @@ end if integrator.opts.adaptive if (integrator.alg isa Rodas5Pe) - du = 0.2606326497975715 * k1 - 0.005158627295444251 * k2 + + @. du = 0.2606326497975715 * k1 - 0.005158627295444251 * k2 + 1.3038988631109731 * k3 + 1.235000722062074 * k4 + -0.7931985603795049 * k5 - 1.005448461135913 * k6 - 0.18044626132120234 * k7 + 0.17051519239113755 * k8