diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 200127f7ef..77516da6f1 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -38,6 +38,7 @@ steps: env: BUILDKITE_PLUGIN_JULIA_VERSION: "{{matrix.version}}" GROUP: "{{matrix.group}}" + JULIA_NUM_THREADS: 2 plugins: - JuliaCI/julia#v1 - staticfloat/metahook: @@ -49,7 +50,6 @@ steps: ' - JuliaCI/julia-test#v1: coverage: false - julia_args: "--threads=auto" agents: os: "linux" queue: "juliaecosystem" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 296ae17352..a3cc456f4e 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -41,6 +41,7 @@ jobs: - OrdinaryDiffEqLinear - OrdinaryDiffEqLowOrderRK - OrdinaryDiffEqLowStorageRK + - OrdinaryDiffEqNonlinearSolve - OrdinaryDiffEqNordsieck - OrdinaryDiffEqPDIRK - OrdinaryDiffEqPRK diff --git a/.github/workflows/Downstream.yml b/.github/workflows/Downstream.yml index dd57d15a64..9938044eb7 100644 --- a/.github/workflows/Downstream.yml +++ b/.github/workflows/Downstream.yml @@ -47,12 +47,6 @@ jobs: # Explicitly develop the libraries first before running the tests for now. # This is necessary since the tests are likely to fail otherwise, given that all # the libs haven't been registered yet. - - name: "Develop the libraries since they haven't been registered yet" - run: | - julia --project=. -e ' - using Pkg; - Pkg.develop(map(path ->Pkg.PackageSpec.(;path="$(@__DIR__)/lib/$(path)"), readdir("./lib"))); - ' - name: Clone Downstream uses: actions/checkout@v4 with: @@ -64,6 +58,7 @@ jobs: using Pkg try # force it to use this PR's version of the package + Pkg.develop(map(path ->Pkg.PackageSpec.(;path="lib/$(path)"), readdir("./lib"))); Pkg.develop(PackageSpec(path=".")) # resolver may fail with main deps Pkg.update() Pkg.test(coverage=true) # resolver may fail with test time deps @@ -79,5 +74,5 @@ jobs: - uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - file: lcov.info - fail_ci_if_error: true + files: lcov.info + fail_ci_if_error: false diff --git a/Project.toml b/Project.toml index bd6935f76f..247b35fcaf 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "OrdinaryDiffEq" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" authors = ["Chris Rackauckas ", "Yingbo Ma "] -version = "6.90.1" +version = "6.91.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -92,7 +92,7 @@ FunctionWrappersWrappers = "0.1" InteractiveUtils = "1.9" LineSearches = "7" LinearAlgebra = "1.9" -LinearSolve = "2" +LinearSolve = "2, 3" Logging = "1.9" MacroTools = "0.5" MuladdMacro = "0.2.1" @@ -133,7 +133,7 @@ PrecompileTools = "1" Preferences = "1.3" RecursiveArrayTools = "2.36, 3" Reexport = "1.0" -SciMLBase = "2.53.2" +SciMLBase = "2.69" SciMLOperators = "0.3" SciMLStructures = "1" SimpleNonlinearSolve = "1, 2" diff --git a/README.md b/README.md index 7d5268ac48..2af90c5a93 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ ordinary differential equation solvers and utilities. While completely independe and usable on its own, users interested in using this functionality should check out [DifferentialEquations.jl](https://github.com/SciML/DifferentialEquations.jl). - ## Installation Assuming that you already have Julia correctly installed, it suffices to import diff --git a/docs/src/dynamicalodeexplicit/SymplecticRK.md b/docs/src/dynamicalodeexplicit/SymplecticRK.md index cd35b08e1b..7ff5ad1c02 100644 --- a/docs/src/dynamicalodeexplicit/SymplecticRK.md +++ b/docs/src/dynamicalodeexplicit/SymplecticRK.md @@ -47,6 +47,7 @@ sol = solve(prob, KahanLi8(), dt = 1 / 10) SymplecticEuler VelocityVerlet VerletLeapfrog +LeapfrogDriftKickDrift PseudoVerletLeapfrog McAte2 Ruth3 diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/Project.toml b/lib/OrdinaryDiffEqAdamsBashforthMoulton/Project.toml index 1c1e832dab..6ada6d599b 100644 --- a/lib/OrdinaryDiffEqAdamsBashforthMoulton/Project.toml +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/Project.toml @@ -1,10 +1,9 @@ name = "OrdinaryDiffEqAdamsBashforthMoulton" uuid = "89bda076-bce5-4f1c-845f-551c83cdda9a" authors = ["ParamThakkar123 "] -version = "1.1.0" +version = "1.2.0" [deps] -ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" @@ -16,7 +15,6 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69" Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" [compat] -ADTypes = "1.7.1" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/OrdinaryDiffEqAdamsBashforthMoulton.jl b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/OrdinaryDiffEqAdamsBashforthMoulton.jl index 070524d8a3..7350b58543 100644 --- a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/OrdinaryDiffEqAdamsBashforthMoulton.jl +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/OrdinaryDiffEqAdamsBashforthMoulton.jl @@ -9,12 +9,12 @@ import OrdinaryDiffEqCore: OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCac constvalue, calculate_residuals, calculate_residuals!, trivial_limiter!, get_fsalfirstlast, generic_solver_docstring, - full_cache + full_cache, + _bool_to_ADType import OrdinaryDiffEqLowOrderRK: BS3ConstantCache, BS3Cache, RK4ConstantCache, RK4Cache import RecursiveArrayTools: recursivefill! using MuladdMacro, FastBroadcast import Static: False -import ADTypes: AutoForwardDiff import OrdinaryDiffEqCore using Reexport diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_caches.jl b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_caches.jl index d417f9cdad..283b4b6b18 100644 --- a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_caches.jl +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_caches.jl @@ -4,7 +4,7 @@ get_fsalfirstlast(cache::ABMMutableCache, u) = (cache.fsalfirst, cache.k) function get_fsalfirstlast(cache::ABMVariableCoefficientMutableCache, u) (cache.fsalfirst, cache.k4) end -@cache mutable struct AB3Cache{uType, rateType} <: ABMMutableCache +@cache mutable struct AB3Cache{uType, rateType, Thread} <: ABMMutableCache u::uType uprev::uType fsalfirst::rateType @@ -14,6 +14,7 @@ end k::rateType tmp::uType step::Int + thread::Thread end @cache mutable struct AB3ConstantCache{rateType} <: OrdinaryDiffEqConstantCache @@ -32,7 +33,7 @@ function alg_cache(alg::AB3, u, rate_prototype, ::Type{uEltypeNoUnits}, ralk2 = zero(rate_prototype) k = zero(rate_prototype) tmp = zero(u) - AB3Cache(u, uprev, fsalfirst, k2, k3, ralk2, k, tmp, 1) + AB3Cache(u, uprev, fsalfirst, k2, k3, ralk2, k, tmp, 1, alg.thread) end function alg_cache(alg::AB3, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -44,7 +45,7 @@ function alg_cache(alg::AB3, u, rate_prototype, ::Type{uEltypeNoUnits}, AB3ConstantCache(k2, k3, 1) end -@cache mutable struct ABM32Cache{uType, rateType} <: ABMMutableCache +@cache mutable struct ABM32Cache{uType, rateType, Thread} <: ABMMutableCache u::uType uprev::uType fsalfirst::rateType @@ -54,6 +55,7 @@ end k::rateType tmp::uType step::Int + thread::Thread end @cache mutable struct ABM32ConstantCache{rateType} <: OrdinaryDiffEqConstantCache @@ -72,7 +74,7 @@ function alg_cache(alg::ABM32, u, rate_prototype, ::Type{uEltypeNoUnits}, ralk2 = zero(rate_prototype) k = zero(rate_prototype) tmp = zero(u) - ABM32Cache(u, uprev, fsalfirst, k2, k3, ralk2, k, tmp, 1) + ABM32Cache(u, uprev, fsalfirst, k2, k3, ralk2, k, tmp, 1, alg.thread) end function alg_cache(alg::ABM32, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -84,7 +86,7 @@ function alg_cache(alg::ABM32, u, rate_prototype, ::Type{uEltypeNoUnits}, ABM32ConstantCache(k2, k3, 1) end -@cache mutable struct AB4Cache{uType, rateType} <: ABMMutableCache +@cache mutable struct AB4Cache{uType, rateType, Thread} <: ABMMutableCache u::uType uprev::uType fsalfirst::rateType @@ -98,6 +100,7 @@ end t3::rateType t4::rateType step::Int + thread::Thread end @cache mutable struct AB4ConstantCache{rateType} <: OrdinaryDiffEqConstantCache @@ -121,7 +124,7 @@ function alg_cache(alg::AB4, u, rate_prototype, ::Type{uEltypeNoUnits}, t2 = zero(rate_prototype) t3 = zero(rate_prototype) t4 = zero(rate_prototype) - AB4Cache(u, uprev, fsalfirst, k2, k3, k4, ralk2, k, tmp, t2, t3, t4, 1) + AB4Cache(u, uprev, fsalfirst, k2, k3, k4, ralk2, k, tmp, t2, t3, t4, 1, alg.thread) end function alg_cache(alg::AB4, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -134,7 +137,7 @@ function alg_cache(alg::AB4, u, rate_prototype, ::Type{uEltypeNoUnits}, AB4ConstantCache(k2, k3, k4, 1) end -@cache mutable struct ABM43Cache{uType, rateType} <: ABMMutableCache +@cache mutable struct ABM43Cache{uType, rateType, Thread} <: ABMMutableCache u::uType uprev::uType fsalfirst::rateType @@ -151,6 +154,7 @@ end t6::rateType t7::rateType step::Int + thread::Thread end @cache mutable struct ABM43ConstantCache{rateType} <: OrdinaryDiffEqConstantCache @@ -177,7 +181,8 @@ function alg_cache(alg::ABM43, u, rate_prototype, ::Type{uEltypeNoUnits}, t5 = zero(rate_prototype) t6 = zero(rate_prototype) t7 = zero(rate_prototype) - ABM43Cache(u, uprev, fsalfirst, k2, k3, k4, ralk2, k, tmp, t2, t3, t4, t5, t6, t7, 1) + ABM43Cache(u, uprev, fsalfirst, k2, k3, k4, ralk2, k, + tmp, t2, t3, t4, t5, t6, t7, 1, alg.thread) end function alg_cache(alg::ABM43, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -190,7 +195,7 @@ function alg_cache(alg::ABM43, u, rate_prototype, ::Type{uEltypeNoUnits}, ABM43ConstantCache(k2, k3, k4, 1) end -@cache mutable struct AB5Cache{uType, rateType} <: ABMMutableCache +@cache mutable struct AB5Cache{uType, rateType, Thread} <: ABMMutableCache u::uType uprev::uType fsalfirst::rateType @@ -204,6 +209,7 @@ end t3::rateType t4::rateType step::Int + thread::Thread end @cache mutable struct AB5ConstantCache{rateType} <: OrdinaryDiffEqConstantCache @@ -228,7 +234,7 @@ function alg_cache(alg::AB5, u, rate_prototype, ::Type{uEltypeNoUnits}, t2 = zero(rate_prototype) t3 = zero(rate_prototype) t4 = zero(rate_prototype) - AB5Cache(u, uprev, fsalfirst, k2, k3, k4, k5, k, tmp, t2, t3, t4, 1) + AB5Cache(u, uprev, fsalfirst, k2, k3, k4, k5, k, tmp, t2, t3, t4, 1, alg.thread) end function alg_cache(alg::AB5, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -242,7 +248,7 @@ function alg_cache(alg::AB5, u, rate_prototype, ::Type{uEltypeNoUnits}, AB5ConstantCache(k2, k3, k4, k5, 1) end -@cache mutable struct ABM54Cache{uType, rateType} <: ABMMutableCache +@cache mutable struct ABM54Cache{uType, rateType, Thread} <: ABMMutableCache u::uType uprev::uType fsalfirst::rateType @@ -260,6 +266,7 @@ end t7::rateType t8::rateType step::Int + thread::Thread end @cache mutable struct ABM54ConstantCache{rateType} <: OrdinaryDiffEqConstantCache @@ -288,7 +295,8 @@ function alg_cache(alg::ABM54, u, rate_prototype, ::Type{uEltypeNoUnits}, t6 = zero(rate_prototype) t7 = zero(rate_prototype) t8 = zero(rate_prototype) - ABM54Cache(u, uprev, fsalfirst, k2, k3, k4, k5, k, tmp, t2, t3, t4, t5, t6, t7, t8, 1) + ABM54Cache(u, uprev, fsalfirst, k2, k3, k4, k5, k, tmp, + t2, t3, t4, t5, t6, t7, t8, 1, alg.thread) end function alg_cache(alg::ABM54, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -317,7 +325,7 @@ end end @cache mutable struct VCAB3Cache{uType, rateType, TabType, bs3Type, tArrayType, cArrayType, - uNoUnitsType, coefType, dtArrayType} <: + uNoUnitsType, coefType, dtArrayType, Thread} <: ABMVariableCoefficientMutableCache u::uType uprev::uType @@ -337,6 +345,7 @@ end utilde::uType tab::TabType step::Int + thread::Thread end function alg_cache(alg::VCAB3, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -395,7 +404,7 @@ function alg_cache(alg::VCAB3, u, rate_prototype, ::Type{uEltypeNoUnits}, tmp = zero(u) utilde = zero(u) VCAB3Cache(u, uprev, fsalfirst, bs3cache, k4, ϕstar_nm1, dts, c, g, ϕ_n, ϕstar_n, β, - order, atmp, tmp, utilde, tab, 1) + order, atmp, tmp, utilde, tab, 1, alg.thread) end @cache mutable struct VCAB4ConstantCache{rk4constcache, tArrayType, rArrayType, cArrayType, @@ -413,7 +422,7 @@ end end @cache mutable struct VCAB4Cache{uType, rateType, rk4cacheType, tArrayType, cArrayType, - uNoUnitsType, coefType, dtArrayType} <: + uNoUnitsType, coefType, dtArrayType, Thread} <: ABMVariableCoefficientMutableCache u::uType uprev::uType @@ -432,6 +441,7 @@ end tmp::uType utilde::uType step::Int + thread::Thread end function alg_cache(alg::VCAB4, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -489,7 +499,7 @@ function alg_cache(alg::VCAB4, u, rate_prototype, ::Type{uEltypeNoUnits}, tmp = zero(u) utilde = zero(u) VCAB4Cache(u, uprev, fsalfirst, rk4cache, k4, ϕstar_nm1, dts, c, g, ϕ_n, ϕstar_n, β, - order, atmp, tmp, utilde, 1) + order, atmp, tmp, utilde, 1, alg.thread) end # VCAB5 @@ -509,7 +519,7 @@ end end @cache mutable struct VCAB5Cache{uType, rateType, rk4cacheType, tArrayType, cArrayType, - uNoUnitsType, coefType, dtArrayType} <: + uNoUnitsType, coefType, dtArrayType, Thread} <: ABMVariableCoefficientMutableCache u::uType uprev::uType @@ -528,6 +538,7 @@ end tmp::uType utilde::uType step::Int + thread::Thread end function alg_cache(alg::VCAB5, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -585,7 +596,7 @@ function alg_cache(alg::VCAB5, u, rate_prototype, ::Type{uEltypeNoUnits}, tmp = zero(u) utilde = zero(u) VCAB5Cache(u, uprev, fsalfirst, rk4cache, k4, ϕstar_nm1, dts, c, g, ϕ_n, ϕstar_n, β, - order, atmp, tmp, utilde, 1) + order, atmp, tmp, utilde, 1, alg.thread) end # VCABM3 @@ -607,7 +618,7 @@ end @cache mutable struct VCABM3Cache{ uType, rateType, TabType, bs3Type, tArrayType, cArrayType, - uNoUnitsType, coefType, dtArrayType} <: + uNoUnitsType, coefType, dtArrayType, Thread} <: ABMVariableCoefficientMutableCache u::uType uprev::uType @@ -628,6 +639,7 @@ end utilde::uType tab::TabType step::Int + thread::Thread end function alg_cache(alg::VCABM3, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -691,7 +703,7 @@ function alg_cache(alg::VCABM3, u, rate_prototype, ::Type{uEltypeNoUnits}, tmp = zero(u) utilde = zero(u) VCABM3Cache(u, uprev, fsalfirst, bs3cache, k4, ϕstar_nm1, dts, c, g, ϕ_n, ϕ_np1, - ϕstar_n, β, order, atmp, tmp, utilde, tab, 1) + ϕstar_n, β, order, atmp, tmp, utilde, tab, 1, alg.thread) end # VCABM4 @@ -713,7 +725,7 @@ end end @cache mutable struct VCABM4Cache{uType, rateType, rk4cacheType, tArrayType, cArrayType, - uNoUnitsType, coefType, dtArrayType} <: + uNoUnitsType, coefType, dtArrayType, Thread} <: ABMVariableCoefficientMutableCache u::uType uprev::uType @@ -733,6 +745,7 @@ end tmp::uType utilde::uType step::Int + thread::Thread end function alg_cache(alg::VCABM4, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -796,7 +809,7 @@ function alg_cache(alg::VCABM4, u, rate_prototype, ::Type{uEltypeNoUnits}, tmp = zero(u) utilde = zero(u) VCABM4Cache(u, uprev, fsalfirst, rk4cache, k4, ϕstar_nm1, dts, c, g, ϕ_n, ϕ_np1, - ϕstar_n, β, order, atmp, tmp, utilde, 1) + ϕstar_n, β, order, atmp, tmp, utilde, 1, alg.thread) end # VCABM5 @@ -818,7 +831,7 @@ end end @cache mutable struct VCABM5Cache{uType, rateType, rk4cacheType, tArrayType, cArrayType, - uNoUnitsType, coefType, dtArrayType} <: + uNoUnitsType, coefType, dtArrayType, Thread} <: ABMVariableCoefficientMutableCache u::uType uprev::uType @@ -838,6 +851,7 @@ end tmp::uType utilde::uType step::Int + thread::Thread end function alg_cache(alg::VCABM5, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -901,7 +915,7 @@ function alg_cache(alg::VCABM5, u, rate_prototype, ::Type{uEltypeNoUnits}, tmp = zero(u) utilde = zero(u) VCABM5Cache(u, uprev, fsalfirst, rk4cache, k4, ϕstar_nm1, dts, c, g, ϕ_n, ϕ_np1, - ϕstar_n, β, order, atmp, tmp, utilde, 1) + ϕstar_n, β, order, atmp, tmp, utilde, 1, alg.thread) end # VCABM @@ -924,7 +938,7 @@ end end @cache mutable struct VCABMCache{uType, rateType, dtType, tArrayType, cArrayType, - uNoUnitsType, coefType, dtArrayType} <: + uNoUnitsType, coefType, dtArrayType, Thread} <: ABMVariableCoefficientMutableCache u::uType uprev::uType @@ -952,6 +966,7 @@ end atmpm2::uNoUnitsType atmpp1::uNoUnitsType step::Int + thread::Thread end function alg_cache(alg::VCABM, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -1023,5 +1038,5 @@ function alg_cache(alg::VCABM, u, rate_prototype, ::Type{uEltypeNoUnits}, VCABMCache( u, uprev, fsalfirst, k4, ϕstar_nm1, dts, c, g, ϕ_n, ϕ_np1, ϕstar_n, β, order, max_order, atmp, tmp, ξ, ξ0, utilde, utildem1, utildem2, utildep1, atmpm1, - atmpm2, atmpp1, 1) + atmpm2, atmpp1, 1, alg.thread) end diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_perform_step.jl b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_perform_step.jl index 077fdfb4ec..e22e68c517 100644 --- a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_perform_step.jl +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/adams_bashforth_moulton_perform_step.jl @@ -68,7 +68,7 @@ end @muladd function perform_step!(integrator, cache::AB3Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k2, k3, ralk2, k = cache + @unpack tmp, fsalfirst, k2, k3, ralk2, k, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -77,17 +77,17 @@ end if cache.step <= 2 cache.step += 1 ttmp = t + (2 / 3) * dt - @.. broadcast=false tmp=uprev + (2 / 3) * dt * k1 + @.. broadcast=false thread=thread tmp=uprev + (2 / 3) * dt * k1 f(ralk2, tmp, p, ttmp) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) - @.. broadcast=false u=uprev + (dt / 4) * (k1 + 3 * ralk2) #Ralston Method + @.. broadcast=false thread=thread u=uprev + (dt / 4) * (k1 + 3 * ralk2) #Ralston Method if cnt == 1 cache.k3 .= k1 else cache.k2 .= k1 end else - @.. broadcast=false u=uprev + (dt / 12) * (23 * k1 - 16 * k2 + 5 * k3) + @.. broadcast=false thread=thread u=uprev + (dt / 12) * (23 * k1 - 16 * k2 + 5 * k3) cache.k2, cache.k3 = k3, k2 cache.k2 .= k1 end @@ -128,7 +128,7 @@ end @muladd function perform_step!(integrator, cache::ABM32Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k2, k3, ralk2, k = cache + @unpack tmp, fsalfirst, k2, k3, ralk2, k, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -137,21 +137,21 @@ end if cache.step == 1 cache.step += 1 ttmp = t + (2 / 3) * dt - @.. broadcast=false tmp=uprev + (2 / 3) * dt * k1 + @.. broadcast=false thread=thread tmp=uprev + (2 / 3) * dt * k1 f(ralk2, tmp, p, ttmp) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) - @.. broadcast=false u=uprev + (dt / 4) * (k1 + 3 * ralk2) #Ralston Method + @.. broadcast=false thread=thread u=uprev + (dt / 4) * (k1 + 3 * ralk2) #Ralston Method cache.k2 .= k1 else if cnt == 2 perform_step!(integrator, - AB3Cache(u, uprev, fsalfirst, copy(k2), k3, ralk2, k, tmp, cnt)) #Here passing copy of k2, otherwise it will change in AB3() + AB3Cache(u, uprev, fsalfirst, copy(k2), k3, ralk2, k, tmp, cnt, thread)) #Here passing copy of k2, otherwise it will change in AB3() else perform_step!(integrator, - AB3Cache(u, uprev, fsalfirst, k2, k3, ralk2, k, tmp, cnt)) + AB3Cache(u, uprev, fsalfirst, k2, k3, ralk2, k, tmp, cnt, thread)) end k = integrator.fsallast - @.. broadcast=false u=uprev + (dt / 12) * (5 * k + 8 * k1 - k2) + @.. broadcast=false thread=thread u=uprev + (dt / 12) * (5 * k + 8 * k1 - k2) cache.k2, cache.k3 = k3, k2 cache.k2 .= k1 end @@ -198,7 +198,7 @@ end @muladd function perform_step!(integrator, cache::AB4Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k2, k3, k4, ralk2, k, t2, t3, t4 = cache + @unpack tmp, fsalfirst, k2, k3, k4, ralk2, k, t2, t3, t4, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -208,14 +208,14 @@ end cache.step += 1 halfdt = dt / 2 ttmp = t + halfdt - @.. broadcast=false tmp=uprev + halfdt * k1 + @.. broadcast=false thread=thread tmp=uprev + halfdt * k1 f(t2, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + halfdt * t2 + @.. broadcast=false thread=thread tmp=uprev + halfdt * t2 f(t3, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + dt * t3 + @.. broadcast=false thread=thread tmp=uprev + dt * t3 f(t4, tmp, p, t + dt) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 3) - @.. broadcast=false u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 + @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 if cnt == 1 cache.k4 .= k1 elseif cnt == 2 @@ -224,7 +224,9 @@ end cache.k2 .= k1 end else - @.. broadcast=false u=uprev + (dt / 24) * (55 * k1 - 59 * k2 + 37 * k3 - 9 * k4) + @.. broadcast=false thread=thread u=uprev + + (dt / 24) * + (55 * k1 - 59 * k2 + 37 * k3 - 9 * k4) cache.k4, cache.k3 = k3, k4 cache.k3 .= k2 cache.k2 .= k1 @@ -272,7 +274,7 @@ end @muladd function perform_step!(integrator, cache::ABM43Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k2, k3, k4, ralk2, k, t2, t3, t4, t5, t6, t7 = cache + @unpack tmp, fsalfirst, k2, k3, k4, ralk2, k, t2, t3, t4, t5, t6, t7, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -282,14 +284,14 @@ end cache.step += 1 halfdt = dt / 2 ttmp = t + halfdt - @.. broadcast=false tmp=uprev + halfdt * k1 + @.. broadcast=false thread=thread tmp=uprev + halfdt * k1 f(t2, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + halfdt * t2 + @.. broadcast=false thread=thread tmp=uprev + halfdt * t2 f(t3, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + dt * t3 + @.. broadcast=false thread=thread tmp=uprev + dt * t3 f(t4, tmp, p, t + dt) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 3) - @.. broadcast=false u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 + @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 if cnt == 1 cache.k3 .= k1 else @@ -301,9 +303,10 @@ end t4 .= k4 perform_step!(integrator, AB4Cache(u, uprev, fsalfirst, t2, t3, t4, ralk2, k, tmp, t5, t6, t7, - cnt)) + cnt, thread)) k = integrator.fsallast - @.. broadcast=false u=uprev + (dt / 24) * (9 * k + 19 * k1 - 5 * k2 + k3) + @.. broadcast=false thread=thread u=uprev + + (dt / 24) * (9 * k + 19 * k1 - 5 * k2 + k3) cache.k4, cache.k3 = k3, k4 cache.k3 .= k2 cache.k2 .= k1 @@ -354,7 +357,7 @@ end @muladd function perform_step!(integrator, cache::AB5Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k2, k3, k4, k5, k, t2, t3, t4 = cache + @unpack tmp, fsalfirst, k2, k3, k4, k5, k, t2, t3, t4, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -364,14 +367,14 @@ end cache.step += 1 halfdt = dt / 2 ttmp = t + halfdt - @.. broadcast=false tmp=uprev + halfdt * k1 + @.. broadcast=false thread=thread tmp=uprev + halfdt * k1 f(t2, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + halfdt * t2 + @.. broadcast=false thread=thread tmp=uprev + halfdt * t2 f(t3, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + dt * t3 + @.. broadcast=false thread=thread tmp=uprev + dt * t3 f(t4, tmp, p, t + dt) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) - @.. broadcast=false u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 + @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 if cnt == 1 cache.k5 .= k1 elseif cnt == 2 @@ -382,9 +385,10 @@ end cache.k2 .= k1 end else - @.. broadcast=false u=uprev + - (dt / 720) * - (1901 * k1 - 2774 * k2 + 2616 * k3 - 1274 * k4 + 251 * k5) + @.. broadcast=false thread=thread u=uprev + + (dt / 720) * + (1901 * k1 - 2774 * k2 + 2616 * k3 - 1274 * k4 + + 251 * k5) cache.k5, cache.k4 = k4, k5 cache.k4 .= k3 cache.k3 .= k2 @@ -436,7 +440,7 @@ end @muladd function perform_step!(integrator, cache::ABM54Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack tmp, fsalfirst, k2, k3, k4, k5, k, t2, t3, t4, t5, t6, t7, t8 = cache + @unpack tmp, fsalfirst, k2, k3, k4, k5, k, t2, t3, t4, t5, t6, t7, t8, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -446,13 +450,13 @@ end cache.step += 1 halfdt = dt / 2 ttmp = t + halfdt - @.. broadcast=false tmp=uprev + halfdt * k1 + @.. broadcast=false thread=thread tmp=uprev + halfdt * k1 f(t2, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + halfdt * t2 + @.. broadcast=false thread=thread tmp=uprev + halfdt * t2 f(t3, tmp, p, ttmp) - @.. broadcast=false tmp=uprev + dt * t3 + @.. broadcast=false thread=thread tmp=uprev + dt * t3 f(t4, tmp, p, t + dt) - @.. broadcast=false u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 + @.. broadcast=false thread=thread u=uprev + (dt / 6) * (2 * (t2 + t3) + (k1 + t4)) #RK4 OrdinaryDiffEqCore.increment_nf!(integrator.stats, 3) if cnt == 1 cache.k4 .= k1 @@ -468,11 +472,12 @@ end t5 .= k5 perform_step!(integrator, AB5Cache(u, uprev, fsalfirst, t2, t3, t4, t5, k, tmp, t6, t7, t8, - cnt)) + cnt, thread)) k = integrator.fsallast - @.. broadcast=false u=uprev + - (dt / 720) * - (251 * k + 646 * k1 - 264 * k2 + 106 * k3 - 19 * k4) + @.. broadcast=false thread=thread u=uprev + + (dt / 720) * + (251 * k + 646 * k1 - 264 * k2 + 106 * k3 - + 19 * k4) cache.k5, cache.k4 = k4, k5 cache.k4 .= k3 cache.k3 .= k2 @@ -561,7 +566,7 @@ end @muladd function perform_step!(integrator, cache::VCAB3Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack k4, dts, g, ϕstar_n, ϕstar_nm1, order, atmp, utilde, bs3cache = cache + @unpack k4, dts, g, ϕstar_n, ϕstar_nm1, order, atmp, utilde, bs3cache, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -587,12 +592,12 @@ end integrator.fsallast .= k4 else g_coefs!(cache, k) - @.. broadcast=false u=uprev + @.. broadcast=false thread=thread u=uprev for i in 1:k - @.. broadcast=false u+=g[i] * ϕstar_n[i] + @.. broadcast=false thread=thread u+=g[i] * ϕstar_n[i] end if integrator.opts.adaptive - @.. broadcast=false utilde=g[k] * ϕstar_n[k] # Using lower order AB from subset of coefficients + @.. broadcast=false thread=thread utilde=g[k] * ϕstar_n[k] # Using lower order AB from subset of coefficients calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) integrator.EEst = integrator.opts.internalnorm(atmp, t) @@ -694,7 +699,7 @@ end @muladd function perform_step!(integrator, cache::VCAB4Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack k4, dts, g, ϕ_n, ϕstar_n, ϕstar_nm1, order, atmp, utilde, rk4cache = cache + @unpack k4, dts, g, ϕ_n, ϕstar_n, ϕstar_nm1, order, atmp, utilde, rk4cache, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -726,12 +731,12 @@ end integrator.fsallast .= rk4cache.k else g_coefs!(cache, k) - @.. broadcast=false u=uprev + @.. broadcast=false thread=thread u=uprev for i in 1:k - @.. broadcast=false u+=g[i] * ϕstar_n[i] + @.. broadcast=false thread=thread u+=g[i] * ϕstar_n[i] end if integrator.opts.adaptive - @.. broadcast=false utilde=g[k] * ϕstar_n[k] + @.. broadcast=false thread=thread utilde=g[k] * ϕstar_n[k] calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) integrator.EEst = integrator.opts.internalnorm(atmp, t) @@ -842,7 +847,7 @@ end @muladd function perform_step!(integrator, cache::VCAB5Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack k4, dts, g, ϕ_n, ϕstar_n, ϕstar_nm1, order, atmp, utilde, rk4cache = cache + @unpack k4, dts, g, ϕ_n, ϕstar_n, ϕstar_nm1, order, atmp, utilde, rk4cache, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -881,12 +886,12 @@ end integrator.fsallast .= rk4cache.k else g_coefs!(cache, k) - @.. broadcast=false u=uprev + @.. broadcast=false thread=thread u=uprev for i in 1:k - @.. broadcast=false u+=g[i] * ϕstar_n[i] + @.. broadcast=false thread=thread u+=g[i] * ϕstar_n[i] end if integrator.opts.adaptive - @.. broadcast=false utilde=g[k] * ϕstar_n[k] + @.. broadcast=false thread=thread utilde=g[k] * ϕstar_n[k] calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) integrator.EEst = integrator.opts.internalnorm(atmp, t) @@ -988,7 +993,7 @@ end @muladd function perform_step!(integrator, cache::VCABM3Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack k4, dts, g, ϕstar_n, ϕ_np1, ϕstar_nm1, order, atmp, utilde, bs3cache = cache + @unpack k4, dts, g, ϕstar_n, ϕ_np1, ϕstar_nm1, order, atmp, utilde, bs3cache, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -1014,16 +1019,16 @@ end integrator.fsallast .= k4 else g_coefs!(cache, k + 1) - @.. broadcast=false u=uprev + @.. broadcast=false thread=thread u=uprev for i in 1:(k - 1) - @.. broadcast=false u+=g[i] * ϕstar_n[i] + @.. broadcast=false thread=thread u+=g[i] * ϕstar_n[i] end f(k4, u, p, t + dt) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) ϕ_np1!(cache, k4, k + 1) - @.. broadcast=false u+=g[end - 1] * ϕ_np1[end - 1] + @.. broadcast=false thread=thread u+=g[end - 1] * ϕ_np1[end - 1] if integrator.opts.adaptive - @.. broadcast=false utilde=(g[end] - g[end - 1]) * ϕ_np1[end] + @.. broadcast=false thread=thread utilde=(g[end] - g[end - 1]) * ϕ_np1[end] calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) integrator.EEst = integrator.opts.internalnorm(atmp, t) @@ -1131,7 +1136,7 @@ end @muladd function perform_step!(integrator, cache::VCABM4Cache, repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack k4, dts, g, ϕstar_n, ϕ_np1, ϕstar_nm1, order, atmp, utilde, rk4cache = cache + @unpack k4, dts, g, ϕstar_n, ϕ_np1, ϕstar_nm1, order, atmp, utilde, rk4cache, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -1163,16 +1168,16 @@ end integrator.fsallast .= rk4cache.k else g_coefs!(cache, k + 1) - @.. broadcast=false u=uprev + @.. broadcast=false thread=thread u=uprev for i in 1:(k - 1) - @.. broadcast=false u+=g[i] * ϕstar_n[i] + @.. broadcast=false thread=thread u+=g[i] * ϕstar_n[i] end f(k4, u, p, t + dt) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) ϕ_np1!(cache, k4, k + 1) - @.. broadcast=false u+=g[end - 1] * ϕ_np1[end - 1] + @.. broadcast=false thread=thread u+=g[end - 1] * ϕ_np1[end - 1] if integrator.opts.adaptive - @.. broadcast=false utilde=(g[end] - g[end - 1]) * ϕ_np1[end] + @.. broadcast=false thread=thread utilde=(g[end] - g[end - 1]) * ϕ_np1[end] calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) integrator.EEst = integrator.opts.internalnorm(atmp, t) @@ -1288,7 +1293,7 @@ end @muladd function perform_step!(integrator, cache::VCABM5Cache, repeat_step = false) @inbounds begin @unpack t, dt, uprev, u, f, p = integrator - @unpack k4, dts, g, ϕ_n, ϕ_np1, ϕstar_n, ϕstar_nm1, order, atmp, utilde, rk4cache = cache + @unpack k4, dts, g, ϕ_n, ϕ_np1, ϕstar_n, ϕstar_nm1, order, atmp, utilde, rk4cache, thread = cache k1 = integrator.fsalfirst if integrator.u_modified cache.step = 1 @@ -1327,16 +1332,16 @@ end integrator.fsallast .= rk4cache.k else g_coefs!(cache, 6) - @.. broadcast=false u=muladd(g[1], ϕstar_n[1], uprev) - @.. broadcast=false u=muladd(g[2], ϕstar_n[2], u) - @.. broadcast=false u=muladd(g[3], ϕstar_n[3], u) - @.. broadcast=false u=muladd(g[4], ϕstar_n[4], u) + @.. broadcast=false thread=thread u=muladd(g[1], ϕstar_n[1], uprev) + @.. broadcast=false thread=thread u=muladd(g[2], ϕstar_n[2], u) + @.. broadcast=false thread=thread u=muladd(g[3], ϕstar_n[3], u) + @.. broadcast=false thread=thread u=muladd(g[4], ϕstar_n[4], u) f(k4, u, p, t + dt) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) ϕ_np1!(cache, k4, 6) - @.. broadcast=false u=muladd(g[6 - 1], ϕ_np1[6 - 1], u) + @.. broadcast=false thread=thread u=muladd(g[6 - 1], ϕ_np1[6 - 1], u) if integrator.opts.adaptive - @.. broadcast=false utilde=(g[6] - g[6 - 1]) * ϕ_np1[end] + @.. broadcast=false thread=thread utilde=(g[6] - g[6 - 1]) * ϕ_np1[end] calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) @@ -1464,7 +1469,7 @@ end @muladd function perform_step!(integrator, cache::VCABMCache, repeat_step = false) @inbounds begin @unpack t, dt, uprev, u, f, p = integrator - @unpack k4, dts, g, ϕ_n, ϕ_np1, ϕstar_n, ϕstar_nm1, order, max_order, utilde, utildem2, utildem1, utildep1, atmp, atmpm1, atmpm2, atmpp1 = cache + @unpack k4, dts, g, ϕ_n, ϕ_np1, ϕstar_n, ϕstar_nm1, order, max_order, utilde, utildem2, utildem1, utildep1, atmp, atmpm1, atmpm2, atmpp1, thread = cache k1 = integrator.fsalfirst step = integrator.iter k = order @@ -1476,16 +1481,16 @@ end ϕ_and_ϕstar!(cache, k1, k) g_coefs!(cache, k + 1) # unroll the predictor once - @.. broadcast=false u=muladd(g[1], ϕstar_n[1], uprev) + @.. broadcast=false thread=thread u=muladd(g[1], ϕstar_n[1], uprev) for i in 2:(k - 1) - @.. broadcast=false u=muladd(g[i], ϕstar_n[i], u) + @.. broadcast=false thread=thread u=muladd(g[i], ϕstar_n[i], u) end f(k4, u, p, t + dt) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) ϕ_np1!(cache, k4, k + 1) - @.. broadcast=false u=muladd(g[k], ϕ_np1[k], u) + @.. broadcast=false thread=thread u=muladd(g[k], ϕ_np1[k], u) if integrator.opts.adaptive - @.. broadcast=false utilde=(g[k + 1] - g[k]) * ϕ_np1[k + 1] + @.. broadcast=false thread=thread utilde=(g[k + 1] - g[k]) * ϕ_np1[k + 1] calculate_residuals!(atmp, utilde, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) integrator.EEst = integrator.opts.internalnorm(atmp, t) @@ -1501,13 +1506,15 @@ end if step <= 4 || order < 3 cache.order = min(order + 1, 3) else - # @.. broadcast=false utildem2 = dt * γstar[(k-2)+1] * ϕ_np1[k-1] - @.. broadcast=false utildem2=(g[k - 1] - g[k - 2]) * ϕ_np1[k - 1] - # @.. broadcast=false utildem1 = dt * γstar[(k-1)+1] * ϕ_np1[k] - @.. broadcast=false utildem1=(g[k] - g[k - 1]) * ϕ_np1[k] + # @.. broadcast=false thread=thread utildem2 = dt * γstar[(k-2)+1] * ϕ_np1[k-1] + @.. broadcast=false thread=thread utildem2=(g[k - 1] - g[k - 2]) * + ϕ_np1[k - 1] + # @.. broadcast=false thread=thread utildem1 = dt * γstar[(k-1)+1] * ϕ_np1[k] + @.. broadcast=false thread=thread utildem1=(g[k] - g[k - 1]) * ϕ_np1[k] expand_ϕ_and_ϕstar!(cache, k + 1) ϕ_np1!(cache, k4, k + 2) - @.. broadcast=false utildep1=dt * γstar[(k + 1) + 1] * ϕ_np1[k + 2] + @.. broadcast=false thread=thread utildep1=dt * γstar[(k + 1) + 1] * + ϕ_np1[k + 2] calculate_residuals!(atmpm2, utildem2, uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/algorithms.jl b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/algorithms.jl index af35c61140..8adf8dbd43 100644 --- a/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/algorithms.jl +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/src/algorithms.jl @@ -3,31 +3,46 @@ reference = """E. Hairer, S. P. Norsett, G. Wanner, Solving Ordinary Differentia Problems. Computational Mathematics (2nd revised ed.), Springer (1996) doi: https://doi.org/10.1007/978-3-540-78862-1""" +keyword_default_description = """ +- `thread`: determines whether internal broadcasting on appropriate CPU arrays should be serial (`thread = OrdinaryDiffEq.False()`) or use multiple threads (`thread = OrdinaryDiffEq.True()`) when Julia is started with multiple threads. +""" + +keyword_default = """ +thread = OrdinaryDiffEq.False(), +""" + @doc generic_solver_docstring("The 3-step third order multistep method. Ralston's Second Order Method is used to calculate starting values.", "AB3", "Adams-Bashforth Explicit Method", reference, - "", - "") -struct AB3 <: OrdinaryDiffEqAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct AB3{Thread} <: OrdinaryDiffEqAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("The 4-step fourth order multistep method. Runge-Kutta method of order 4 is used to calculate starting values.", "AB4", "Adams-Bashforth Explicit Method", reference, - "", - "") -struct AB4 <: OrdinaryDiffEqAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct AB4{Thread} <: OrdinaryDiffEqAlgorithm + thread::Thread = False() +end + @doc generic_solver_docstring("The 5-step fifth order multistep method. Ralston's 3rd order Runge-Kutta method is used to calculate starting values.", "AB5", "Adams-Bashforth Explicit Method", reference, - "", - "") -struct AB5 <: OrdinaryDiffEqAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct AB5{Thread} <: OrdinaryDiffEqAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("It is third order method. In ABM32, AB3 works as predictor and Adams Moulton 2-steps method works as Corrector. @@ -35,9 +50,11 @@ struct AB5 <: OrdinaryDiffEqAlgorithm end "ABM32", "Adams-Bashforth Explicit Method", reference, - "", - "") -struct ABM32 <: OrdinaryDiffEqAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct ABM32{Thread} <: OrdinaryDiffEqAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("It is fourth order method. In ABM43, AB4 works as predictor and Adams Moulton 3-steps method works as Corrector. @@ -45,9 +62,11 @@ struct ABM32 <: OrdinaryDiffEqAlgorithm end "ABM43", "Adams-Bashforth Explicit Method", reference, - "", - "") -struct ABM43 <: OrdinaryDiffEqAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct ABM43{Thread} <: OrdinaryDiffEqAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("It is fifth order method. In ABM54, AB5 works as predictor and Adams Moulton 4-steps method works as Corrector. @@ -55,9 +74,11 @@ struct ABM43 <: OrdinaryDiffEqAlgorithm end "ABM54", "Adams-Bashforth Explicit Method", reference, - "", - "") -struct ABM54 <: OrdinaryDiffEqAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct ABM54{Thread} <: OrdinaryDiffEqAlgorithm + thread::Thread = False() +end # Variable Step Size Adams methods @@ -66,54 +87,66 @@ struct ABM54 <: OrdinaryDiffEqAlgorithm end "VCAB3", "Adams explicit Method", reference, - "", - "") -struct VCAB3 <: OrdinaryDiffEqAdaptiveAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct VCAB3{Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("The 4th order Adams method. Runge-Kutta 4 is used to calculate starting values.", "VCAB4", "Adams explicit Method", reference, - "", - "") -struct VCAB4 <: OrdinaryDiffEqAdaptiveAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct VCAB4{Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("The 5th order Adams method. Runge-Kutta 4 is used to calculate starting values.", "VCAB5", "Adams explicit Method", reference, - "", - "") -struct VCAB5 <: OrdinaryDiffEqAdaptiveAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct VCAB5{Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("The 3rd order Adams-Moulton method. Bogacki-Shampine 3/2 method is used to calculate starting values.", "VCABM3", "Adams explicit Method", reference, - "", - "") -struct VCABM3 <: OrdinaryDiffEqAdaptiveAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct VCABM3{Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("The 4th order Adams-Moulton method. Runge-Kutta 4 is used to calculate starting values.", "VCABM4", "Adams explicit Method", reference, - "", - "") -struct VCABM4 <: OrdinaryDiffEqAdaptiveAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct VCABM4{Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + thread::Thread = False() +end @doc generic_solver_docstring("The 5th order Adams-Moulton method. Runge-Kutta 4 is used to calculate starting values.", "VCABM5", "Adams explicit Method", reference, - "", - "") -struct VCABM5 <: OrdinaryDiffEqAdaptiveAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct VCABM5{Thread} <: OrdinaryDiffEqAdaptiveAlgorithm + thread::Thread = False() +end # Variable Order and Variable Step Size Adams methods @@ -122,6 +155,8 @@ struct VCABM5 <: OrdinaryDiffEqAdaptiveAlgorithm end "VCABM", "adaptive order Adams explicit Method", reference, - "", - "") -struct VCABM <: OrdinaryDiffEqAdamsVarOrderVarStepAlgorithm end + keyword_default_description, + keyword_default) +Base.@kwdef struct VCABM{Thread} <: OrdinaryDiffEqAdamsVarOrderVarStepAlgorithm + thread::Thread = False() +end diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/abm_convergence_tests.jl b/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/abm_convergence_tests.jl index ccebddd73e..ffe01a7d71 100644 --- a/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/abm_convergence_tests.jl +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/abm_convergence_tests.jl @@ -37,3 +37,21 @@ testTol = 0.2 sim106 = test_convergence(dts, prob, VCABM5()) @test sim106.𝒪est[:l2]≈5 atol=testTol end + +@testset "Explicit Solver Convergence Tests ($(["out-of-place", "in-place"][i])) - threaded " for i in 1:2 + prob = (ODEProblemLibrary.prob_ode_linear, + ODEProblemLibrary.prob_ode_2Dlinear)[i] + + sim5 = test_convergence(dts, prob, AB3(true)) + @test sim5.𝒪est[:l2]≈3 atol=testTol + sim7 = test_convergence(dts, prob, AB4(true)) + @test sim7.𝒪est[:l2]≈4 atol=testTol + sim9 = test_convergence(dts, prob, AB5(true)) + @test sim9.𝒪est[:l2]≈5 atol=testTol + sim101 = test_convergence(dts, prob, VCAB3(true)) + @test sim101.𝒪est[:l2]≈3 atol=testTol + sim103 = test_convergence(dts, prob, VCAB5(true)) + @test sim103.𝒪est[:l2]≈5 atol=testTol + sim105 = test_convergence(dts, prob, VCABM4(true)) + @test sim105.𝒪est[:l2]≈4 atol=testTol +end diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/regression_test_threading.jl b/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/regression_test_threading.jl new file mode 100644 index 0000000000..b70a6b11cb --- /dev/null +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/regression_test_threading.jl @@ -0,0 +1,22 @@ +using OrdinaryDiffEqAdamsBashforthMoulton, ODEProblemLibrary +import OrdinaryDiffEqCore: OrdinaryDiffEqAdaptiveAlgorithm +using Test +using Static + +algorithms = [ + AB3, AB4, AB5, ABM32, ABM43, ABM54, VCAB3, VCAB4, VCAB5, VCABM3, VCABM4, VCABM5, VCABM] + +problem = ODEProblemLibrary.prob_ode_linear + +@testset "Regression test for threading versions vs non threading versions" begin + @testset "$ALG" for ALG in algorithms + if ALG isa OrdinaryDiffEqAdaptiveAlgorithm + sol_thread = solve(problem, ALG(Static.True())) + sol_nothread = solve(problem, ALG(Static.False())) + else + sol_thread = solve(problem, ALG(Static.True()), dt = 1 // 2^9) + sol_nothread = solve(problem, ALG(Static.False()), dt = 1 // 2^9) + end + @test all(sol_nothread .== sol_thread) + end +end diff --git a/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/runtests.jl b/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/runtests.jl index a0518e6f70..fd3e5ee9a4 100644 --- a/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/runtests.jl +++ b/lib/OrdinaryDiffEqAdamsBashforthMoulton/test/runtests.jl @@ -2,3 +2,4 @@ using SafeTestsets @time @safetestset "ABM Convergence Tests" include("abm_convergence_tests.jl") @time @safetestset "Adams Variable Coefficients Tests" include("adams_tests.jl") +@time @safetestset "Regression test for threading versions vs non threading versions" include("regression_test_threading.jl") diff --git a/lib/OrdinaryDiffEqBDF/Project.toml b/lib/OrdinaryDiffEqBDF/Project.toml index b5f182aff6..f02261db32 100644 --- a/lib/OrdinaryDiffEqBDF/Project.toml +++ b/lib/OrdinaryDiffEqBDF/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqBDF" uuid = "6ad6398a-0878-4a85-9266-38940aa047c8" authors = ["ParamThakkar123 "] -version = "1.1.2" +version = "1.2.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" @@ -22,6 +23,7 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" [compat] +ADTypes = "1.11" ArrayInterface = "7.15.0" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" @@ -31,7 +33,7 @@ LinearAlgebra = "<0.0.1, 1" MacroTools = "0.5.13" MuladdMacro = "0.2.4" ODEProblemLibrary = "0.1.8" -OrdinaryDiffEqCore = "1.1" +OrdinaryDiffEqCore = "1.14" OrdinaryDiffEqDifferentiation = "<0.0.1, 1" OrdinaryDiffEqNonlinearSolve = "<0.0.1, 1" OrdinaryDiffEqSDIRK = "<0.0.1, 1" diff --git a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl index 5a2981219b..6821fc464b 100644 --- a/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl +++ b/lib/OrdinaryDiffEqBDF/src/OrdinaryDiffEqBDF.jl @@ -20,7 +20,8 @@ import OrdinaryDiffEqCore: alg_order, calculate_residuals!, step_accept_controller!, step_reject_controller!, post_newton_controller!, u_modified!, DAEAlgorithm, _unwrap_val, DummyController, - get_fsalfirstlast, generic_solver_docstring + get_fsalfirstlast, generic_solver_docstring, _bool_to_ADType, + _process_AD_choice using OrdinaryDiffEqSDIRK: ImplicitEulerConstantCache, ImplicitEulerCache using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools @@ -32,6 +33,8 @@ using OrdinaryDiffEqDifferentiation: UJacobianWrapper using OrdinaryDiffEqNonlinearSolve: NLNewton, du_alias_or_new, build_nlsolver, nlsolve!, nlsolvefail, isnewton, markfirststage!, set_new_W!, DIRK, compute_step!, COEFFICIENT_MULTISTEP +import ADTypes +import ADTypes: AutoForwardDiff, AutoFiniteDiff, AbstractADType using Reexport @reexport using DiffEqBase diff --git a/lib/OrdinaryDiffEqBDF/src/algorithms.jl b/lib/OrdinaryDiffEqBDF/src/algorithms.jl index 494bbcfa8a..14ce9c75e1 100644 --- a/lib/OrdinaryDiffEqBDF/src/algorithms.jl +++ b/lib/OrdinaryDiffEqBDF/src/algorithms.jl @@ -5,21 +5,22 @@ function BDF_docstring(description::String, extra_keyword_default::String = "") keyword_default = """ chunk_size = Val{0}(), - autodiff = true, + autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = nothing, precs = DEFAULT_PRECS, """ * "\n" * extra_keyword_default keyword_default_description = """ - - `chunk_size`: The chunk size used with ForwardDiff.jl. Defaults to `Val{0}()` - and thus uses the internal ForwardDiff.jl algorithm for the choice. - - `autodiff`: Specifies whether to use automatic differentiation via + - `autodiff`: Uses [ADTypes.jl](https://sciml.github.io/ADTypes.jl/stable/) + to specify whether to use automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) or finite - differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). - Defaults to `Val{true}()` for automatic differentiation. + differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). + Defaults to `AutoForwardDiff()` for automatic differentiation, which by default uses + `chunksize = 0`, and thus uses the internal ForwardDiff.jl algorithm for the choice. + To use `FiniteDiff.jl`, the `AutoFiniteDiff()` ADType can be used, which has a keyword argument + `fdtype` with default value `Val{:forward}()`, and alternatives `Val{:central}()` and `Val{:complex}()`. - `standardtag`: Specifies whether to use package-specific tags instead of the ForwardDiff default function-specific tags. For more information, see [this blog post](https://www.stochasticlifestyle.com/improved-forwarddiff-jl-stacktraces-with-package-tags/). @@ -27,9 +28,6 @@ function BDF_docstring(description::String, - `concrete_jac`: Specifies whether a Jacobian should be constructed. Defaults to `nothing`, which means it will be chosen true/false depending on circumstances of the solver, such as whether a Krylov subspace method is used for `linsolve`. - - `diff_type`: The type of differentiation used in FiniteDiff.jl if `autodiff=false`. - Defaults to `Val{:forward}`, with alternatives of `Val{:central}` and - `Val{:complex}`. - `linsolve`: Any [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) compatible linear solver. For example, to use [KLU.jl](https://github.com/JuliaSparse/KLU.jl), specify `$name(linsolve = KLUFactorization()`). @@ -112,18 +110,22 @@ struct ABDF2{CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function ABDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function ABDF2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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!) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + ABDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + _unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end @doc BDF_docstring( @@ -167,14 +169,17 @@ struct SBDF{CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: extrapolant::Symbol order::Int ark::Bool + autodiff::AD end -function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, +function SBDF(order; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SBDF{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(κ), typeof(tol)}(linsolve, nlsolve, @@ -183,17 +188,21 @@ function SBDF(order; chunk_size = Val{0}(), autodiff = Val{true}(), tol, extrapolant, order, - ark) + ark, + AD_choice) 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}, +function SBDF(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SBDF{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(κ), typeof(tol)}(linsolve, nlsolve, @@ -202,7 +211,8 @@ function SBDF(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val tol, extrapolant, order, - ark) + ark, + AD_choice) end """ @@ -287,15 +297,19 @@ struct QNDF1{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: kappa::κType controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function QNDF1(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear, kappa = -37 // 200, controller = :Standard, step_limiter! = trivial_limiter!) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + QNDF1{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + _unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(kappa), typeof(step_limiter!)}(linsolve, nlsolve, @@ -303,7 +317,8 @@ function QNDF1(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Va extrapolant, kappa, controller, - step_limiter!) + step_limiter!, + AD_choice) end @doc BDF_docstring( @@ -342,15 +357,19 @@ struct QNDF2{CS, AD, F, F2, P, FDT, ST, CJ, κType, StepLimiter} <: kappa::κType controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function QNDF2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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!) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + QNDF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + _unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(kappa), typeof(step_limiter!)}(linsolve, nlsolve, @@ -358,7 +377,8 @@ function QNDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Va extrapolant, kappa, controller, - step_limiter!) + step_limiter!, + AD_choice) end @doc BDF_docstring( @@ -405,22 +425,25 @@ struct QNDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, κType, StepLimiter} <: kappa::κType controller::Symbol step_limiter!::StepLimiter + autodiff::AD 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}, + autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, tol = nothing, extrapolant = :linear, kappa = ( -37 // 200, -1 // 9, -823 // 10000, -83 // 2000, 0 // 1), controller = :Standard, step_limiter! = trivial_limiter!) where {MO} - QNDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + QNDF{MO, _unwrap_val(chunk_size), typeof(AD_choice), 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!) + extrapolant, kappa, controller, step_limiter!, AD_choice) end TruncatedStacktraces.@truncate_stacktrace QNDF @@ -452,17 +475,22 @@ struct MEBDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function MEBDF2(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function MEBDF2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + MEBDF2{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc BDF_docstring( @@ -504,20 +532,23 @@ struct FBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD 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}, + autodiff = AutoForwardDiff(), 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + FBDF{MO, _unwrap_val(chunk_size), typeof(AD_choice), 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!) + controller, step_limiter!, AD_choice) end TruncatedStacktraces.@truncate_stacktrace FBDF @@ -620,17 +651,20 @@ struct DImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT precs::P extrapolant::Symbol controller::Symbol + autodiff::AD end function DImplicitEuler(; - chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :constant, controller = :Standard) - DImplicitEuler{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + DImplicitEuler{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) + nlsolve, precs, extrapolant, controller, AD_choice) end @doc BDF_docstring("Fully implicit implementation of BDF2.", @@ -659,16 +693,20 @@ struct DABDF2{CS, AD, F, F2, P, FDT, ST, CJ} <: DAEAlgorithm{CS, AD, FDT, ST, CJ precs::P extrapolant::Symbol controller::Symbol + autodiff::AD end -function DABDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function DABDF2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :constant, controller = :Standard) - DABDF2{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + DABDF2{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, - nlsolve, precs, extrapolant, controller) + nlsolve, precs, extrapolant, controller, AD_choice) end #= @@ -718,18 +756,21 @@ struct DFBDF{MO, CS, AD, F, F2, P, FDT, ST, CJ, K, T} <: DAEAlgorithm{CS, AD, FD tol::T extrapolant::Symbol controller::Symbol + autodiff::AD end function DFBDF(; max_order::Val{MO} = Val{5}(), chunk_size = Val{0}(), - autodiff = Val{true}(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, tol = nothing, extrapolant = :linear, controller = :Standard) where {MO} - DFBDF{MO, _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + DFBDF{MO, _unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(κ), typeof(tol)}(max_order, linsolve, nlsolve, precs, κ, tol, extrapolant, - controller) + controller, AD_choice) end TruncatedStacktraces.@truncate_stacktrace DFBDF diff --git a/lib/OrdinaryDiffEqBDF/test/bdf_regression_tests.jl b/lib/OrdinaryDiffEqBDF/test/bdf_regression_tests.jl index 9369d189e5..293abccf4d 100644 --- a/lib/OrdinaryDiffEqBDF/test/bdf_regression_tests.jl +++ b/lib/OrdinaryDiffEqBDF/test/bdf_regression_tests.jl @@ -1,20 +1,20 @@ using OrdinaryDiffEqBDF, Test -foop = (u,p,t)->u +foop = (u, p, t) -> u proboop = ODEProblem(foop, ones(2), (0.0, 1000.0)) -fiip = (du,u,p,t)->du.=u +fiip = (du, u, p, t) -> du .= u probiip = ODEProblem(fiip, ones(2), (0.0, 1000.0)) @testset "FBDF reinit" begin -for prob in [proboop, probiip] - integ = init(prob, FBDF(), verbose=false) #suppress warning to clean up CI - solve!(integ) - @test integ.sol.retcode != ReturnCode.Success - @test integ.sol.t[end] >= 700 - reinit!(integ, prob.u0) - solve!(integ) - @test integ.sol.retcode != ReturnCode.Success - @test integ.sol.t[end] >= 700 -end + for prob in [proboop, probiip] + integ = init(prob, FBDF(), verbose = false) #suppress warning to clean up CI + solve!(integ) + @test integ.sol.retcode != ReturnCode.Success + @test integ.sol.t[end] >= 700 + reinit!(integ, prob.u0) + solve!(integ) + @test integ.sol.retcode != ReturnCode.Success + @test integ.sol.t[end] >= 700 + end end diff --git a/lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl index bd0d5891c4..1829c679a0 100644 --- a/lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl +++ b/lib/OrdinaryDiffEqBDF/test/dae_convergence_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEqBDF, DiffEqDevTools +using OrdinaryDiffEqBDF, DiffEqDevTools, ADTypes using Test, Random Random.seed!(100) @@ -22,13 +22,13 @@ prob_dae_linear_iip = DAEProblem( sim11 = test_convergence(dts, prob, DImplicitEuler()) @test sim11.𝒪est[:final]≈1 atol=testTol - sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = AutoFiniteDiff())) @test sim12.𝒪est[:final]≈1 atol=testTol sim13 = test_convergence(dts, prob, DABDF2()) @test sim13.𝒪est[:final]≈2 atol=testTol - sim14 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + sim14 = test_convergence(dts, prob, DABDF2(; autodiff = AutoFiniteDiff())) @test sim14.𝒪est[:final]≈2 atol=testTol @test_nowarn solve(prob, DFBDF()) @@ -46,13 +46,13 @@ prob_dae_linear_iip_jac = DAEProblem( sim11 = test_convergence(dts, prob, DImplicitEuler()) @test sim11.𝒪est[:final]≈1 atol=testTol - sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + sim12 = test_convergence(dts, prob, DImplicitEuler(; autodiff = AutoFiniteDiff())) @test sim12.𝒪est[:final]≈1 atol=testTol sim13 = test_convergence(dts, prob, DABDF2()) @test sim13.𝒪est[:final]≈2 atol=testTol - sim14 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + sim14 = test_convergence(dts, prob, DABDF2(; autodiff = AutoFiniteDiff())) @test sim14.𝒪est[:final]≈2 atol=testTol @test_nowarn solve(prob, DFBDF()) @@ -76,13 +76,13 @@ prob_dae_linear_oop = DAEProblem( sim21 = test_convergence(dts, prob, DImplicitEuler()) @test sim21.𝒪est[:final]≈1 atol=testTol - sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = AutoFiniteDiff())) @test sim22.𝒪est[:final]≈1 atol=testTol sim23 = test_convergence(dts, prob, DABDF2()) @test sim23.𝒪est[:final]≈2 atol=testTol - sim24 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + sim24 = test_convergence(dts, prob, DABDF2(; autodiff = AutoFiniteDiff())) @test sim24.𝒪est[:final]≈2 atol=testTol @test_nowarn solve(prob, DFBDF()) @@ -100,13 +100,13 @@ prob_dae_linear_oop = DAEProblem( sim21 = test_convergence(dts, prob, DImplicitEuler()) @test sim21.𝒪est[:final]≈1 atol=testTol - sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = false)) + sim22 = test_convergence(dts, prob, DImplicitEuler(; autodiff = AutoFiniteDiff())) @test sim22.𝒪est[:final]≈1 atol=testTol sim23 = test_convergence(dts, prob, DABDF2()) @test sim23.𝒪est[:final]≈2 atol=testTol - sim24 = test_convergence(dts, prob, DABDF2(; autodiff = false)) + sim24 = test_convergence(dts, prob, DABDF2(; autodiff = AutoFiniteDiff())) @test sim24.𝒪est[:final]≈2 atol=testTol @test_nowarn solve(prob, DFBDF()) diff --git a/lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl b/lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl index cc8d574fd1..154f499c07 100644 --- a/lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl +++ b/lib/OrdinaryDiffEqBDF/test/dae_initialization_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEqBDF, StaticArrays, LinearAlgebra, Test +using OrdinaryDiffEqBDF, StaticArrays, LinearAlgebra, Test, ADTypes using OrdinaryDiffEqNonlinearSolve f = function (du, u, p, t) @@ -56,7 +56,7 @@ tspan = (0.0, 100000.0) differential_vars = [true, true, false] prob = DAEProblem(f, du₀, u₀, tspan, differential_vars = differential_vars) integrator = init(prob, DABDF2()) -integrator2 = init(prob, DABDF2(autodiff = false)) +integrator2 = init(prob, DABDF2(autodiff = AutoFiniteDiff())) @test integrator.du[1]≈-0.04 atol=1e-9 @test integrator.du[2]≈0.04 atol=1e-9 diff --git a/lib/OrdinaryDiffEqCore/Project.toml b/lib/OrdinaryDiffEqCore/Project.toml index f5f381c9a0..4a83585c3b 100644 --- a/lib/OrdinaryDiffEqCore/Project.toml +++ b/lib/OrdinaryDiffEqCore/Project.toml @@ -1,7 +1,7 @@ name = "OrdinaryDiffEqCore" uuid = "bbf590c4-e513-4bbe-9b18-05decba2e5d8" authors = ["ParamThakkar123 "] -version = "1.13.0" +version = "1.17.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -70,7 +70,7 @@ Random = "<0.0.1, 1" RecursiveArrayTools = "2.36, 3" Reexport = "1.0" SafeTestsets = "0.1.0" -SciMLBase = "2.62" +SciMLBase = "2.68" SciMLOperators = "0.3" SciMLStructures = "1" SimpleUnPack = "1" diff --git a/lib/OrdinaryDiffEqCore/ext/OrdinaryDiffEqCoreEnzymeCoreExt.jl b/lib/OrdinaryDiffEqCore/ext/OrdinaryDiffEqCoreEnzymeCoreExt.jl index 888c54bb27..908d5cb8e1 100644 --- a/lib/OrdinaryDiffEqCore/ext/OrdinaryDiffEqCoreEnzymeCoreExt.jl +++ b/lib/OrdinaryDiffEqCore/ext/OrdinaryDiffEqCoreEnzymeCoreExt.jl @@ -1,7 +1,10 @@ module OrdinaryDiffEqCoreEnzymeCoreExt import OrdinaryDiffEqCore, EnzymeCore -EnzymeCore.EnzymeRules.inactive_noinl(::typeof(OrdinaryDiffEqCore.increment_nf!), args...) = true +function EnzymeCore.EnzymeRules.inactive_noinl( + ::typeof(OrdinaryDiffEqCore.increment_nf!), args...) + true +end function EnzymeCore.EnzymeRules.inactive_noinl( ::typeof(OrdinaryDiffEqCore.fixed_t_for_floatingpoint_error!), args...) true @@ -14,7 +17,13 @@ function EnzymeCore.EnzymeRules.inactive_noinl( ::typeof(OrdinaryDiffEqCore.increment_reject!), args...) true end -EnzymeCore.EnzymeRules.inactive_noinl(::typeof(OrdinaryDiffEqCore.check_error!), args...) = true -EnzymeCore.EnzymeRules.inactive_noinl(::typeof(OrdinaryDiffEqCore.log_step!), args...) = true +function EnzymeCore.EnzymeRules.inactive_noinl( + ::typeof(OrdinaryDiffEqCore.check_error!), args...) + true +end +function EnzymeCore.EnzymeRules.inactive_noinl( + ::typeof(OrdinaryDiffEqCore.log_step!), args...) + true +end end diff --git a/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl b/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl index fbfcd66dd3..fd049c064a 100644 --- a/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl +++ b/lib/OrdinaryDiffEqCore/src/OrdinaryDiffEqCore.jl @@ -60,7 +60,8 @@ using DiffEqBase: check_error!, @def, _vec, _reshape using FastBroadcast: @.., True, False -using SciMLBase: NoInit, CheckInit, OverrideInit, AbstractDEProblem, _unwrap_val +using SciMLBase: NoInit, CheckInit, OverrideInit, AbstractDEProblem, _unwrap_val, + ODEAliasSpecifier import SciMLBase: AbstractNonlinearProblem, alg_order @@ -71,12 +72,13 @@ import DiffEqBase: calculate_residuals, import Polyester using MacroTools, Adapt -import ADTypes: AutoFiniteDiff, AutoForwardDiff +import ADTypes: AutoFiniteDiff, AutoForwardDiff, AbstractADType import Accessors: @reset using SciMLStructures: canonicalize, Tunable, isscimlstructure -using SymbolicIndexingInterface: state_values, parameter_values, is_variable, variable_index, +using SymbolicIndexingInterface: state_values, parameter_values, is_variable, + variable_index, symbolic_type, NotSymbolic const CompiledFloats = Union{Float32, Float64} @@ -115,6 +117,12 @@ const TryAgain = SlowConvergence DEFAULT_PRECS(W, du, u, p, t, newW, Plprev, Prprev, solverdata) = nothing, nothing isdiscretecache(cache) = false +@static if isdefined(DiffEqBase, :unitfulvalue) + unitfulvalue(x) = DiffEqBase.unitfulvalue(x) +else + unitfulvalue(x) = DiffEqBase.ForwardDiff.value(x) +end + include("doc_utils.jl") include("misc_utils.jl") diff --git a/lib/OrdinaryDiffEqCore/src/alg_utils.jl b/lib/OrdinaryDiffEqCore/src/alg_utils.jl index d5f89349d6..a7ef37a7bf 100644 --- a/lib/OrdinaryDiffEqCore/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqCore/src/alg_utils.jl @@ -171,26 +171,39 @@ end function get_chunksize(alg::OrdinaryDiffEqAlgorithm) error("This algorithm does not have a chunk size defined.") end -function get_chunksize(alg::Union{OrdinaryDiffEqExponentialAlgorithm{CS}, - OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS}, - OrdinaryDiffEqImplicitAlgorithm{CS}, - OrdinaryDiffEqAdaptiveImplicitAlgorithm{CS}, - DAEAlgorithm{CS}, - CompositeAlgorithm{CS}}) where {CS} - Val(CS) + +_get_fwd_chunksize(::Type{<:AutoForwardDiff{CS}}) where {CS} = Val(CS) +_get_fwd_chunksize_int(::Type{<:AutoForwardDiff{CS}}) where {CS} = CS +_get_fwd_chunksize(AD) = Val(0) +_get_fwd_chunksize_int(AD) = 0 +_get_fwd_tag(::AutoForwardDiff{CS, T}) where {CS, T} = T + +_get_fdtype(::AutoFiniteDiff{T1}) where {T1} = T1 +_get_fdtype(::Type{<:AutoFiniteDiff{T1}}) where {T1} = T1 + +function get_chunksize(alg::Union{OrdinaryDiffEqExponentialAlgorithm{CS, AD}, + OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD}, + OrdinaryDiffEqImplicitAlgorithm{CS, AD}, + OrdinaryDiffEqAdaptiveImplicitAlgorithm{CS, AD}, + DAEAlgorithm{CS, AD}, + CompositeAlgorithm{CS, AD}}) where {CS, AD} + _get_fwd_chunksize(AD) end function get_chunksize_int(alg::OrdinaryDiffEqAlgorithm) error("This algorithm does not have a chunk size defined.") end -function get_chunksize_int(alg::Union{OrdinaryDiffEqExponentialAlgorithm{CS}, + +function get_chunksize_int(alg::Union{ + OrdinaryDiffEqExponentialAlgorithm{CS}, OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS}, - OrdinaryDiffEqImplicitAlgorithm{CS}, - OrdinaryDiffEqAdaptiveImplicitAlgorithm{CS}, - DAEAlgorithm{CS}, - CompositeAlgorithm{CS}}) where {CS} - CS + OrdinaryDiffEqImplicitAlgorithm{CS, AD}, + OrdinaryDiffEqAdaptiveImplicitAlgorithm{CS, AD}, + DAEAlgorithm{CS, AD}, + CompositeAlgorithm{CS, AD}}) where {CS, AD} + _get_fwd_chunksize_int(AD) end + # get_chunksize(alg::CompositeAlgorithm) = get_chunksize(alg.algs[alg.current_alg]) function alg_autodiff end @@ -232,7 +245,7 @@ function alg_difftype(alg::Union{ CJ}, DAEAlgorithm{CS, AD, FDT, ST, CJ}}) where {CS, AD, FDT, ST, CJ} - FDT + _get_fdtype(AD) end function standardtag(alg::Union{ @@ -444,3 +457,6 @@ function Base.show(io::IO, ::MIME"text/plain", alg::OrdinaryDiffEqAlgorithm) end print(io, ")") end + +# Defaults in the current system: currently opt out DAEAlgorithms until complete +default_linear_interpolation(alg, prob) = alg isa DAEAlgorithm || prob isa DiscreteProblem diff --git a/lib/OrdinaryDiffEqCore/src/algorithms.jl b/lib/OrdinaryDiffEqCore/src/algorithms.jl index 01c24467a6..1b2a535467 100644 --- a/lib/OrdinaryDiffEqCore/src/algorithms.jl +++ b/lib/OrdinaryDiffEqCore/src/algorithms.jl @@ -61,7 +61,7 @@ function DiffEqBase.remake( kwargs...) where {CS, AD, FDT, ST, CJ} T = SciMLBase.remaker_of(thing) T(; SciMLBase.struct_as_namedtuple(thing)..., - chunk_size = Val{CS}(), autodiff = Val{AD}(), standardtag = Val{ST}(), + chunk_size = Val{CS}(), autodiff = thing.autodiff, standardtag = Val{ST}(), concrete_jac = CJ === nothing ? CJ : Val{CJ}(), kwargs...) end @@ -88,7 +88,7 @@ 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) + CS = mapreduce(alg -> 0, max, algs) new{CS, T, F}(algs, choice_function) end end diff --git a/lib/OrdinaryDiffEqCore/src/doc_utils.jl b/lib/OrdinaryDiffEqCore/src/doc_utils.jl index 75eb00dc7d..44872a3585 100644 --- a/lib/OrdinaryDiffEqCore/src/doc_utils.jl +++ b/lib/OrdinaryDiffEqCore/src/doc_utils.jl @@ -82,7 +82,7 @@ function differentiation_rk_docstring(description::String, extra_keyword_default::String = "") keyword_default = """ chunk_size = Val{0}(), - autodiff = true, + autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:forward}, @@ -91,12 +91,14 @@ function differentiation_rk_docstring(description::String, """ * extra_keyword_default keyword_default_description = """ - - `chunk_size`: The chunk size used with ForwardDiff.jl. Defaults to `Val{0}()` - and thus uses the internal ForwardDiff.jl algorithm for the choice. - - `autodiff`: Specifies whether to use automatic differentiation via + - `autodiff`: Uses [ADTypes.jl](https://sciml.github.io/ADTypes.jl/stable/) + to specify whether to use automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) or finite - differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). - Defaults to `Val{true}()` for automatic differentiation. + differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). + Defaults to `AutoForwardDiff()` for automatic differentiation, which by default uses + `chunksize = 0`, and thus uses the internal ForwardDiff.jl algorithm for the choice. + To use `FiniteDiff.jl`, the `AutoFiniteDiff()` ADType can be used, which has a keyword argument + `fdtype` with default value `Val{:forward}()`, and alternatives `Val{:central}()` and `Val{:complex}()`. - `standardtag`: Specifies whether to use package-specific tags instead of the ForwardDiff default function-specific tags. For more information, see [this blog post](https://www.stochasticlifestyle.com/improved-forwarddiff-jl-stacktraces-with-package-tags/). @@ -104,9 +106,6 @@ function differentiation_rk_docstring(description::String, - `concrete_jac`: Specifies whether a Jacobian should be constructed. Defaults to `nothing`, which means it will be chosen true/false depending on circumstances of the solver, such as whether a Krylov subspace method is used for `linsolve`. - - `diff_type`: The type of differentiation used in FiniteDiff.jl if `autodiff=false`. - Defaults to `Val{:forward}`, with alternatives of `Val{:central}` and - `Val{:complex}`. - `linsolve`: Any [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) compatible linear solver. For example, to use [KLU.jl](https://github.com/JuliaSparse/KLU.jl), specify `$name(linsolve = KLUFactorization()`). diff --git a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl index 0034e55d9a..aa6d828b66 100644 --- a/lib/OrdinaryDiffEqCore/src/initialize_dae.jl +++ b/lib/OrdinaryDiffEqCore/src/initialize_dae.jl @@ -44,53 +44,16 @@ end ## Default algorithms -function _initialize_dae!(integrator, prob::ODEProblem, - alg::DefaultInit, x::Val{true}) +function _initialize_dae!(integrator, + prob::Union{ODEProblem, DAEProblem}, + alg::DefaultInit, + x::Union{Val{true}, Val{false}}) if SciMLBase.has_initializeprob(prob.f) _initialize_dae!(integrator, prob, OverrideInit(integrator.opts.abstol), x) else _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) - end -end - -function _initialize_dae!(integrator, prob::ODEProblem, - alg::DefaultInit, x::Val{false}) - if SciMLBase.has_initializeprob(prob.f) - _initialize_dae!(integrator, prob, - OverrideInit(integrator.opts.abstol), x) - else - _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) - end -end - -function _initialize_dae!(integrator, prob::DAEProblem, - alg::DefaultInit, x::Val{false}) - if SciMLBase.has_initializeprob(prob.f) - _initialize_dae!(integrator, prob, - OverrideInit(integrator.opts.abstol), x) - elseif prob.differential_vars === nothing - _initialize_dae!(integrator, prob, - ShampineCollocationInit(), x) - else - _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) - end -end - -function _initialize_dae!(integrator, prob::DAEProblem, - alg::DefaultInit, x::Val{true}) - if SciMLBase.has_initializeprob(prob.f) - _initialize_dae!(integrator, prob, - OverrideInit(integrator.opts.abstol), x) - elseif prob.differential_vars === nothing - _initialize_dae!(integrator, prob, - ShampineCollocationInit(), x) - else - _initialize_dae!(integrator, prob, - BrownFullBasicInit(integrator.opts.abstol), x) + CheckInit(), x) end end @@ -157,7 +120,9 @@ function _initialize_dae!(integrator, prob::AbstractDEProblem, nlsolve_alg = default_nlsolve(alg.nlsolve, isinplace, iu0, initializeprob, isAD) - u0, p, success = SciMLBase.get_initial_values(prob, integrator, prob.f, alg, isinplace; nlsolve_alg, abstol = integrator.opts.abstol, reltol = integrator.opts.reltol) + u0, p, success = SciMLBase.get_initial_values( + prob, integrator, prob.f, alg, isinplace; nlsolve_alg, + abstol = integrator.opts.abstol, reltol = integrator.opts.reltol) if isinplace === Val{true}() integrator.u .= u0 @@ -178,7 +143,98 @@ function _initialize_dae!(integrator, prob::AbstractDEProblem, end ## CheckInit +struct CheckInitFailureError <: Exception + normresid::Any + abstol::Any +end + +function Base.showerror(io::IO, e::CheckInitFailureError) + print(io, + "DAE initialization failed: your u0 did not satisfy the initialization requirements, + normresid = $(e.normresid) > abstol = $(e.abstol). If you wish for the system to + automatically change the algebraic variables to satisfy the algebraic constraints, + please pass `initializealg = BrownBasicInit()` to solve (this option will require + `using OrdinaryDiffEqNonlinearSolve`). If you wish to perform an initialization on the + complete u0, please pass initializealg = ShampineCollocationInit() to solve. Note that + initialization can be a very difficult process for DAEs and in many cases can be + numerically intractable without symbolic manipulation of the system. For an automated + system that will generate numerically stable initializations, see ModelingToolkit.jl + structural simplification for more details." + ) +end + +function _initialize_dae!(integrator, prob::ODEProblem, alg::CheckInit, + isinplace::Val{true}) + @unpack p, t, f = integrator + M = integrator.f.mass_matrix + tmp = first(get_tmp_cache(integrator)) + u0 = integrator.u + + algebraic_vars = [all(iszero, x) for x in eachcol(M)] + algebraic_eqs = [all(iszero, x) for x in eachrow(M)] + (iszero(algebraic_vars) || iszero(algebraic_eqs)) && return + update_coefficients!(M, u0, p, t) + f(tmp, u0, p, t) + tmp .= ArrayInterface.restructure(tmp, algebraic_eqs .* _vec(tmp)) + + normresid = integrator.opts.internalnorm(tmp, t) + if normresid > integrator.opts.abstol + throw(CheckInitFailureError(normresid, integrator.opts.abstol)) + end +end + +function _initialize_dae!(integrator, prob::ODEProblem, alg::CheckInit, + isinplace::Val{false}) + @unpack p, t, f = integrator + u0 = integrator.u + M = integrator.f.mass_matrix + + algebraic_vars = [all(iszero, x) for x in eachcol(M)] + algebraic_eqs = [all(iszero, x) for x in eachrow(M)] + (iszero(algebraic_vars) || iszero(algebraic_eqs)) && return + update_coefficients!(M, u0, p, t) + du = f(u0, p, t) + resid = _vec(du)[algebraic_eqs] + + normresid = integrator.opts.internalnorm(resid, t) + if normresid > integrator.opts.abstol + throw(CheckInitFailureError(normresid, integrator.opts.abstol)) + end +end + +function _initialize_dae!(integrator, prob::DAEProblem, + alg::CheckInit, isinplace::Val{true}) + @unpack p, t, f = integrator + u0 = integrator.u + resid = get_tmp_cache(integrator)[2] + + f(resid, integrator.du, u0, p, t) + normresid = integrator.opts.internalnorm(resid, t) + if normresid > integrator.opts.abstol + throw(CheckInitFailureError(normresid, integrator.opts.abstol)) + end +end + +function _initialize_dae!(integrator, prob::DAEProblem, + alg::CheckInit, isinplace::Val{false}) + @unpack p, t, f = integrator + u0 = integrator.u + + nlequation_oop = u -> begin + f((u - u0) / dt, u, p, t) + end + + nlequation = (u, _) -> nlequation_oop(u) + + resid = f(integrator.du, u0, p, t) + normresid = integrator.opts.internalnorm(resid, t) + if normresid > integrator.opts.abstol + throw(CheckInitFailureError(normresid, integrator.opts.abstol)) + end +end + function _initialize_dae!(integrator, prob::AbstractDEProblem, alg::CheckInit, isinplace::Union{Val{true}, Val{false}}) - SciMLBase.get_initial_values(prob, integrator, prob.f, alg, isinplace; abstol = integrator.opts.abstol) + SciMLBase.get_initial_values( + prob, integrator, prob.f, alg, isinplace; abstol = integrator.opts.abstol) end diff --git a/lib/OrdinaryDiffEqCore/src/integrators/controllers.jl b/lib/OrdinaryDiffEqCore/src/integrators/controllers.jl index a38ce1566a..9e28020851 100644 --- a/lib/OrdinaryDiffEqCore/src/integrators/controllers.jl +++ b/lib/OrdinaryDiffEqCore/src/integrators/controllers.jl @@ -141,8 +141,8 @@ end if iszero(EEst) q = inv(qmax) else - q11 = FastPower.fastpower(EEst, convert(typeof(EEst),beta1)) - q = q11 / FastPower.fastpower(qold, convert(typeof(EEst),beta2)) + q11 = FastPower.fastpower(EEst, convert(typeof(EEst), beta1)) + q = q11 / FastPower.fastpower(qold, convert(typeof(EEst), beta2)) integrator.q11 = q11 @fastmath q = max(inv(qmax), min(inv(qmin), q / gamma)) end @@ -428,7 +428,7 @@ 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) if integrator.success_iter > 0 @@ -445,11 +445,11 @@ function step_accept_controller!(integrator, controller::PredictiveController, a end integrator.dtacc = integrator.dt integrator.erracc = max(1e-2, EEst) - + return integrator.dt / qacc end function step_reject_controller!(integrator, controller::PredictiveController, alg) @unpack dt, success_iter, qold = integrator integrator.dt = success_iter == 0 ? 0.1 * dt : dt / qold -end \ No newline at end of file +end diff --git a/lib/OrdinaryDiffEqCore/src/integrators/integrator_interface.jl b/lib/OrdinaryDiffEqCore/src/integrators/integrator_interface.jl index e64e03dc39..91e6631962 100644 --- a/lib/OrdinaryDiffEqCore/src/integrators/integrator_interface.jl +++ b/lib/OrdinaryDiffEqCore/src/integrators/integrator_interface.jl @@ -3,7 +3,7 @@ # Hence, we need to have two separate functions. function _change_t_via_interpolation!(integrator, t, - modify_save_endpoint::Type{Val{T}}, reinitialize_alg=nothing) where {T} + modify_save_endpoint::Type{Val{T}}, reinitialize_alg = nothing) where {T} # Can get rid of an allocation here with a function # get_tmp_arr(integrator.cache) which gives a pointer to some # cache array which can be modified. @@ -17,7 +17,8 @@ function _change_t_via_interpolation!(integrator, t, end integrator.t = t integrator.dt = integrator.t - integrator.tprev - DiffEqBase.reeval_internals_due_to_modification!(integrator; callback_initializealg=reinitialize_alg) + DiffEqBase.reeval_internals_due_to_modification!( + integrator; callback_initializealg = reinitialize_alg) if T solution_endpoint_match_cur_integrator!(integrator) end @@ -28,7 +29,7 @@ function DiffEqBase.change_t_via_interpolation!(integrator::ODEIntegrator, t, modify_save_endpoint::Type{Val{T}} = Val{ false, - }, reinitialize_alg=nothing) where { + }, reinitialize_alg = nothing) where { T, } _change_t_via_interpolation!(integrator, t, modify_save_endpoint, reinitialize_alg) diff --git a/lib/OrdinaryDiffEqCore/src/iterator_interface.jl b/lib/OrdinaryDiffEqCore/src/iterator_interface.jl index 09828e042b..66bdd67fb0 100644 --- a/lib/OrdinaryDiffEqCore/src/iterator_interface.jl +++ b/lib/OrdinaryDiffEqCore/src/iterator_interface.jl @@ -1,25 +1,26 @@ -@inline function step!(integrator::ODEIntegrator) +function step!(integrator::ODEIntegrator) if integrator.opts.advance_to_tstop - @inbounds while integrator.tdir * integrator.t < first(integrator.opts.tstops) + while integrator.tdir * integrator.t < first(integrator.opts.tstops) loopheader!(integrator) (integrator.do_error_check && check_error!(integrator) != ReturnCode.Success) && - return + return integrator.sol.retcode perform_step!(integrator, integrator.cache) loopfooter!(integrator) end else - @inbounds loopheader!(integrator) + loopheader!(integrator) (integrator.do_error_check && check_error!(integrator) != ReturnCode.Success) && - return - @inbounds perform_step!(integrator, integrator.cache) - @inbounds loopfooter!(integrator) - @inbounds while !integrator.accept_step + return integrator.sol.retcode + perform_step!(integrator, integrator.cache) + loopfooter!(integrator) + while !integrator.accept_step loopheader!(integrator) (integrator.do_error_check && check_error!(integrator) != ReturnCode.Success) && - return + return integrator.sol.retcode perform_step!(integrator, integrator.cache) loopfooter!(integrator) end end - @inbounds handle_tstop!(integrator) + handle_tstop!(integrator) + return integrator.sol.retcode end diff --git a/lib/OrdinaryDiffEqCore/src/misc_utils.jl b/lib/OrdinaryDiffEqCore/src/misc_utils.jl index c6f67947eb..b39e7ab54d 100644 --- a/lib/OrdinaryDiffEqCore/src/misc_utils.jl +++ b/lib/OrdinaryDiffEqCore/src/misc_utils.jl @@ -130,3 +130,34 @@ function get_differential_vars(f, u) end isnewton(::Any) = false + +function _bool_to_ADType(::Val{true}, chunksize, diff_type) + Base.depwarn( + "Using a `Bool` for keyword argument `autodiff` is deprecated. Please use an `ADType` specifier.", + :_bool_to_ADType) + chunksize = SciMLBase._unwrap_val(chunksize) == 0 ? nothing : + SciMLBase._unwrap_val(chunksize) + AutoForwardDiff(chunksize = chunksize) +end + +function _bool_to_ADType(::Val{false}, chunksize, diff_type) + Base.depwarn( + "Using a `Bool` for keyword argument `autodiff` is deprecated. Please use an `ADType` specifier.", + :_bool_to_ADType) + return AutoFiniteDiff(fdtype = diff_type) +end + +# Functions to get ADType type from Bool or ADType object, or ADType type +function _process_AD_choice(ad_alg::Bool, chunksize, diff_type) + _bool_to_ADType(Val(ad_alg), chunksize, diff_type) +end + +function _process_AD_choice(ad_alg::AbstractADType, chunksize, diff_type) + # need a path for if just chunksize is specified in the Algorithm construction + if !(chunksize === Val{0}()) + @warn "The `chunksize` keyword is deprecated. Please use an `ADType` specifier. For now defaulting to using `ForwardDiff` with the given `chunksize`." + return _bool_to_ADType(Val{true}(), chunksize, diff_type) + end + + ad_alg +end diff --git a/lib/OrdinaryDiffEqCore/src/solve.jl b/lib/OrdinaryDiffEqCore/src/solve.jl index 42fd07a5bf..6cbd4742e2 100644 --- a/lib/OrdinaryDiffEqCore/src/solve.jl +++ b/lib/OrdinaryDiffEqCore/src/solve.jl @@ -26,9 +26,8 @@ function DiffEqBase.__init( saveat isa Number || prob.tspan[1] in saveat, save_end = nothing, callback = nothing, - dense = save_everystep && - !(alg isa DAEAlgorithm) && !(prob isa DiscreteProblem) && - isempty(saveat), + dense = save_everystep && isempty(saveat) && + !default_linear_interpolation(prob, alg), calck = (callback !== nothing && callback !== CallbackSet()) || (dense) || !isempty(saveat), # and no dense output dt = isdiscretealg(alg) && isempty(tstops) ? @@ -69,8 +68,7 @@ function DiffEqBase.__init( userdata = nothing, allow_extrapolation = alg_extrapolates(alg), initialize_integrator = true, - alias_u0 = false, - alias_du0 = false, + alias = ODEAliasSpecifier(), initializealg = DefaultInit(), kwargs...) where {recompile_flag} if prob isa DiffEqBase.AbstractDAEProblem && alg isa OrdinaryDiffEqAlgorithm @@ -158,19 +156,63 @@ function DiffEqBase.__init( else _alg = alg end - f = prob.f - p = prob.p - # Get the control variables + use_old_kwargs = haskey(kwargs, :alias_u0) || haskey(kwargs, :alias_du0) - if alias_u0 + if use_old_kwargs + aliases = ODEAliasSpecifier() + if haskey(kwargs, :alias_u0) + message = "`alias_u0` keyword argument is deprecated, to set `alias_u0`, + please use an ODEAliasSpecifier, e.g. `solve(prob, alias = ODEAliasSpecifier(alias_u0 = true))" + Base.depwarn(message, :init) + Base.depwarn(message, :solve) + aliases = ODEAliasSpecifier(alias_u0 = values(kwargs).alias_u0) + else + aliases = ODEAliasSpecifier(alias_u0 = nothing) + end + + if haskey(kwargs, :alias_du0) + message = "`alias_du0` keyword argument is deprecated, to set `alias_du0`, + please use an ODEAliasSpecifier, e.g. `solve(prob, alias = ODEAliasSpecifier(alias_du0 = true))" + Base.depwarn(message, :init) + Base.depwarn(message, :solve) + aliases = ODEAliasSpecifier( + alias_u0 = aliases.alias_u0, alias_du0 = values(kwargs).alias_du0) + else + aliases = ODEAliasSpecifier(alias_u0 = aliases.alias_u0, alias_du0 = nothing) + end + + aliases + + else + # If alias isa Bool, all fields of ODEAliases set to alias + if alias isa Bool + aliases = ODEAliasSpecifier(alias = alias) + elseif alias isa ODEAliasSpecifier + aliases = alias + end + end + + if isnothing(aliases.alias_f) || aliases.alias_f + f = prob.f + else + f = deepcopy(prob.f) + end + + if isnothing(aliases.alias_p) || aliases.alias_p + p = prob.p + else + p = recursivecopy(prob.p) + end + + if !isnothing(aliases.alias_u0) && aliases.alias_u0 u = prob.u0 else u = recursivecopy(prob.u0) end if _alg isa DAEAlgorithm - if alias_du0 + if !isnothing(aliases.alias_du0) && aliases.alias_du0 du = prob.du0 else du = recursivecopy(prob.du0) @@ -192,11 +234,11 @@ function DiffEqBase.__init( abstol_internal = false elseif abstol === nothing if uBottomEltypeNoUnits == uBottomEltype - abstol_internal = DiffEqBase.ForwardDiff.value(real(convert(uBottomEltype, + abstol_internal = unitfulvalue(real(convert(uBottomEltype, oneunit(uBottomEltype) * 1 // 10^6))) else - abstol_internal = DiffEqBase.ForwardDiff.value.(real.(oneunit.(u) .* 1 // 10^6)) + abstol_internal = unitfulvalue.(real.(oneunit.(u) .* 1 // 10^6)) end else abstol_internal = real.(abstol) @@ -206,10 +248,10 @@ function DiffEqBase.__init( reltol_internal = false elseif reltol === nothing if uBottomEltypeNoUnits == uBottomEltype - reltol_internal = DiffEqBase.ForwardDiff.value(real(convert(uBottomEltype, + reltol_internal = unitfulvalue(real(convert(uBottomEltype, oneunit(uBottomEltype) * 1 // 10^3))) else - reltol_internal = DiffEqBase.ForwardDiff.value.(real.(oneunit.(u) .* 1 // 10^3)) + reltol_internal = unitfulvalue.(real.(oneunit.(u) .* 1 // 10^3)) end else reltol_internal = real.(reltol) @@ -242,6 +284,12 @@ function DiffEqBase.__init( resType = typeof(res_prototype) end + if isnothing(aliases.alias_tstops) || aliases.alias_tstops + tstops = tstops + else + tstops = recursivecopy(tstops) + end + if tstops isa AbstractArray || tstops isa Tuple || tstops isa Number _tstops = nothing else @@ -270,7 +318,8 @@ function DiffEqBase.__init( end ### Algorithm-specific defaults ### - save_idxs, saved_subsystem = SciMLBase.get_save_idxs_and_saved_subsystem(prob, save_idxs) + save_idxs, saved_subsystem = SciMLBase.get_save_idxs_and_saved_subsystem( + prob, save_idxs) if save_idxs === nothing ksEltype = Vector{rateType} @@ -471,7 +520,9 @@ function DiffEqBase.__init( do_error_check = true event_last_time = 0 vector_event_last_time = 1 - last_event_error = prob isa DiscreteProblem ? false : zero(uBottomEltypeNoUnits) + last_event_error = prob isa DiscreteProblem ? false : + (Base.isbitstype(uBottomEltypeNoUnits) ? zero(uBottomEltypeNoUnits) : + 0.0) dtchangeable = isdtchangeable(_alg) q11 = QT(1) success_iter = 0 diff --git a/lib/OrdinaryDiffEqDefault/Project.toml b/lib/OrdinaryDiffEqDefault/Project.toml index 6962deaa5f..fe52df48ac 100644 --- a/lib/OrdinaryDiffEqDefault/Project.toml +++ b/lib/OrdinaryDiffEqDefault/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqDefault" uuid = "50262376-6c5a-4cf5-baba-aaf4f84d72d7" authors = ["ParamThakkar123 "] -version = "1.1.0" +version = "1.2.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" EnumX = "4e289a0a-7415-4d19-859d-a7e5c4648b56" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -18,13 +19,14 @@ Preferences = "21216c6a-2e73-6563-6e65-726566657250" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" EnumX = "1.0.4" LinearAlgebra = "<0.0.1, 1" LinearSolve = "2.32.0" OrdinaryDiffEqBDF = "<0.0.1, 1" -OrdinaryDiffEqCore = "1.1" +OrdinaryDiffEqCore = "1.14" OrdinaryDiffEqRosenbrock = "<0.0.1, 1" OrdinaryDiffEqTsit5 = "<0.0.1, 1" OrdinaryDiffEqVerner = "<0.0.1, 1" diff --git a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl index 182b3c70c1..a5ecee57c5 100644 --- a/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl +++ b/lib/OrdinaryDiffEqDefault/src/OrdinaryDiffEqDefault.jl @@ -11,6 +11,7 @@ using OrdinaryDiffEqBDF: FBDF import OrdinaryDiffEqCore import OrdinaryDiffEqCore: is_mass_matrix_alg, default_autoswitch, isdefaultalg +import ADTypes: AutoFiniteDiff, AutoForwardDiff, AbstractADType import LinearSolve using LinearAlgebra: I, isdiag using EnumX @@ -29,7 +30,7 @@ PrecompileTools.@compile_workload begin prob_list = [] default_ode = [ - DefaultODEAlgorithm(autodiff = false) + DefaultODEAlgorithm(autodiff = AutoFiniteDiff()) ] default_autodiff_ode = [ diff --git a/lib/OrdinaryDiffEqDefault/src/default_alg.jl b/lib/OrdinaryDiffEqDefault/src/default_alg.jl index 9347a6192c..9ec64e3fed 100644 --- a/lib/OrdinaryDiffEqDefault/src/default_alg.jl +++ b/lib/OrdinaryDiffEqDefault/src/default_alg.jl @@ -40,10 +40,14 @@ function isdefaultalg(alg::CompositeAlgorithm{ end function DiffEqBase.__init(prob::ODEProblem, ::Nothing, args...; kwargs...) - DiffEqBase.init(prob, DefaultODEAlgorithm(autodiff = false), args...; wrap = Val(false), kwargs...) + DiffEqBase.init( + prob, DefaultODEAlgorithm(autodiff = AutoFiniteDiff()), + args...; wrap = Val(false), kwargs...) end function DiffEqBase.__solve(prob::ODEProblem, ::Nothing, args...; kwargs...) - DiffEqBase.solve(prob, DefaultODEAlgorithm(autodiff = false), args...; wrap = Val(false), kwargs...) + DiffEqBase.solve( + prob, DefaultODEAlgorithm(autodiff = AutoFiniteDiff()), + args...; wrap = Val(false), kwargs...) end function is_stiff(integrator, alg, ntol, stol, is_stiffalg, current) @@ -81,7 +85,7 @@ function stiffchoice(reltol, len, mass_matrix) elseif len > SMALLSIZE DefaultSolverChoice.FBDF else - if reltol < LOW_TOL || !isdiag(mass_matrix) + if reltol < LOW_TOL || mass_matrix != I DefaultSolverChoice.Rodas5P else DefaultSolverChoice.Rosenbrock23 diff --git a/lib/OrdinaryDiffEqDefault/test/default_solver_tests.jl b/lib/OrdinaryDiffEqDefault/test/default_solver_tests.jl index c434bc80ab..b1c39f5a3f 100644 --- a/lib/OrdinaryDiffEqDefault/test/default_solver_tests.jl +++ b/lib/OrdinaryDiffEqDefault/test/default_solver_tests.jl @@ -1,5 +1,5 @@ using OrdinaryDiffEqDefault, OrdinaryDiffEqTsit5, OrdinaryDiffEqVerner, - OrdinaryDiffEqRosenbrock, OrdinaryDiffEqBDF + OrdinaryDiffEqRosenbrock, OrdinaryDiffEqBDF, ADTypes using Test, LinearSolve, LinearAlgebra, SparseArrays, StaticArrays f_2dlinear = (du, u, p, t) -> (@. du = p * u) @@ -27,7 +27,7 @@ vernsol = solve(prob_ode_2Dlinear, Vern7(), reltol = 1e-10) prob_ode_linear_fast = ODEProblem( ODEFunction(f_2dlinear, mass_matrix = 2 * I(2)), rand(2), (0.0, 1.0), 1.01) sol = solve(prob_ode_linear_fast) -@test all(isequal(3), sol.alg_choice) +@test all(isequal(4), sol.alg_choice) # for some reason the timestepping here is different from regular Rosenbrock23 (including the initial timestep) function rober(u, p, t) @@ -39,7 +39,7 @@ function rober(u, p, t) end prob_rober = ODEProblem(rober, [1.0, 0.0, 0.0], (0.0, 1e3), (0.04, 3e7, 1e4)) sol = solve(prob_rober) -rosensol = solve(prob_rober, AutoTsit5(Rosenbrock23(autodiff = false))) +rosensol = solve(prob_rober, AutoTsit5(Rosenbrock23(autodiff = AutoFiniteDiff()))) #test that cache is type stable @test typeof(sol.interp.cache.cache3) == typeof(rosensol.interp.cache.caches[2]) # test that default has the same performance as AutoTsit5(Rosenbrock23()) (which we expect it to use for this). @@ -51,7 +51,7 @@ rosensol = solve(prob_rober, AutoTsit5(Rosenbrock23(autodiff = false))) sol = solve(prob_rober, reltol = 1e-7, abstol = 1e-7) rosensol = solve( - prob_rober, AutoVern7(Rodas5P(autodiff = false)), reltol = 1e-7, abstol = 1e-7) + prob_rober, AutoVern7(Rodas5P(autodiff = AutoFiniteDiff())), reltol = 1e-7, abstol = 1e-7) #test that cache is type stable @test typeof(sol.interp.cache.cache4) == typeof(rosensol.interp.cache.caches[2]) # test that default has the same performance as AutoTsit5(Rosenbrock23()) (which we expect it to use for this). @@ -79,7 +79,7 @@ for n in (100, 600) prob_ex_rober = ODEProblem(ODEFunction(exrober; jac_prototype), vcat([1.0, 0.0, 0.0], ones(n)), (0.0, 100.0), (0.04, 3e7, 1e4)) global sol = solve(prob_ex_rober) - fsol = solve(prob_ex_rober, AutoTsit5(FBDF(; autodiff = false, linsolve))) + fsol = solve(prob_ex_rober, AutoTsit5(FBDF(; autodiff = AutoFiniteDiff(), linsolve))) # test that default has the same performance as AutoTsit5(Rosenbrock23()) (which we expect it to use for this). @test sol.stats.naccept == fsol.stats.naccept @test sol.stats.nf == fsol.stats.nf @@ -108,7 +108,7 @@ end f = ODEFunction(rober_mm, mass_matrix = [1 0 0; 0 1 0; 0 0 0]) prob_rober_mm = ODEProblem(f, [1.0, 0.0, 1.0], (0.0, 1e5), (0.04, 3e7, 1e4)) sol = solve(prob_rober_mm) -@test all(isequal(3), sol.alg_choice) +@test all(isequal(4), sol.alg_choice) @test sol(0.5) isa Vector{Float64} # test dense output # test callback on ConstantCache (https://github.com/SciML/OrdinaryDiffEq.jl/issues/2287) diff --git a/lib/OrdinaryDiffEqDifferentiation/Project.toml b/lib/OrdinaryDiffEqDifferentiation/Project.toml index 11d8b4cfb0..f32ee0d56a 100644 --- a/lib/OrdinaryDiffEqDifferentiation/Project.toml +++ b/lib/OrdinaryDiffEqDifferentiation/Project.toml @@ -1,7 +1,7 @@ name = "OrdinaryDiffEqDifferentiation" uuid = "4302a76b-040a-498a-8c04-15b101fed76b" authors = ["Chris Rackauckas ", "Yingbo Ma "] -version = "1.2.0" +version = "1.4.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -21,7 +21,7 @@ StaticArrayInterface = "0d7ed370-da01-4f52-bd93-41d350b8b718" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] -ADTypes = "1" +ADTypes = "1.11" ArrayInterface = "7" DiffEqBase = "6" DiffEqDevTools = "2.44.4" @@ -30,8 +30,8 @@ FiniteDiff = "2" ForwardDiff = "0.10" FunctionWrappersWrappers = "0.1" LinearAlgebra = "1.10" -LinearSolve = "2" -OrdinaryDiffEqCore = "1.1" +LinearSolve = "2, 3" +OrdinaryDiffEqCore = "1.14" Random = "<0.0.1, 1" SafeTestsets = "0.1.0" SciMLBase = "2" diff --git a/lib/OrdinaryDiffEqDifferentiation/src/OrdinaryDiffEqDifferentiation.jl b/lib/OrdinaryDiffEqDifferentiation/src/OrdinaryDiffEqDifferentiation.jl index bc1e42339d..25a696c778 100644 --- a/lib/OrdinaryDiffEqDifferentiation/src/OrdinaryDiffEqDifferentiation.jl +++ b/lib/OrdinaryDiffEqDifferentiation/src/OrdinaryDiffEqDifferentiation.jl @@ -1,6 +1,6 @@ module OrdinaryDiffEqDifferentiation -import ADTypes: AutoFiniteDiff, AutoForwardDiff +import ADTypes: AutoFiniteDiff, AutoForwardDiff, AbstractADType import SparseDiffTools: SparseDiffTools, matrix_colors, forwarddiff_color_jacobian!, forwarddiff_color_jacobian, ForwardColorJacCache, @@ -27,7 +27,7 @@ import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, S using DiffEqBase: TimeGradientWrapper, UJacobianWrapper, TimeDerivativeWrapper, UDerivativeWrapper -using SciMLBase: AbstractSciMLOperator +using SciMLBase: AbstractSciMLOperator, constructorof import OrdinaryDiffEqCore using OrdinaryDiffEqCore: OrdinaryDiffEqAlgorithm, OrdinaryDiffEqAdaptiveImplicitAlgorithm, DAEAlgorithm, @@ -44,7 +44,8 @@ using OrdinaryDiffEqCore: OrdinaryDiffEqAlgorithm, OrdinaryDiffEqAdaptiveImplici FastConvergence, Convergence, SlowConvergence, VerySlowConvergence, Divergence, NLStatus, MethodType, constvalue -import OrdinaryDiffEqCore: get_chunksize, resize_J_W!, resize_nlsolver!, alg_autodiff +import OrdinaryDiffEqCore: get_chunksize, resize_J_W!, resize_nlsolver!, alg_autodiff, + _get_fwd_tag using FastBroadcast: @.. diff --git a/lib/OrdinaryDiffEqDifferentiation/src/alg_utils.jl b/lib/OrdinaryDiffEqDifferentiation/src/alg_utils.jl index 50e605e409..354bbcb463 100644 --- a/lib/OrdinaryDiffEqDifferentiation/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqDifferentiation/src/alg_utils.jl @@ -2,26 +2,29 @@ function _alg_autodiff(alg::OrdinaryDiffEqAlgorithm) error("This algorithm does not have an autodifferentiation option defined.") end -_alg_autodiff(::OrdinaryDiffEqAdaptiveImplicitAlgorithm{CS, AD}) where {CS, AD} = Val{AD}() -_alg_autodiff(::DAEAlgorithm{CS, AD}) where {CS, AD} = Val{AD}() -_alg_autodiff(::OrdinaryDiffEqImplicitAlgorithm{CS, AD}) where {CS, AD} = Val{AD}() +function _alg_autodiff(alg::OrdinaryDiffEqAdaptiveImplicitAlgorithm{CS, AD}) where {CS, AD} + alg.autodiff +end +_alg_autodiff(alg::DAEAlgorithm{CS, AD}) where {CS, AD} = alg.autodiff +_alg_autodiff(alg::OrdinaryDiffEqImplicitAlgorithm{CS, AD}) where {CS, AD} = alg.autodiff _alg_autodiff(alg::CompositeAlgorithm) = _alg_autodiff(alg.algs[end]) -function _alg_autodiff(::Union{OrdinaryDiffEqExponentialAlgorithm{CS, AD}, +function _alg_autodiff(alg::Union{OrdinaryDiffEqExponentialAlgorithm{CS, AD}, OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD} }) where { CS, AD } - Val{AD}() + alg.autodiff end function alg_autodiff(alg) autodiff = _alg_autodiff(alg) - if autodiff == Val(false) - return AutoFiniteDiff() - elseif autodiff == Val(true) + + if autodiff == Val(true) return AutoForwardDiff() + elseif autodiff == Val(false) + return AutoFiniteDiff() else - return _unwrap_val(autodiff) + return autodiff end end @@ -48,11 +51,24 @@ function DiffEqBase.prepare_alg( # If not using autodiff or norecompile mode or very large bitsize (like a dual number u0 already) # don't use a large chunksize as it will either error or not be beneficial - if !(alg_autodiff(alg) isa AutoForwardDiff) || - (isbitstype(T) && sizeof(T) > 24) || - (prob.f isa ODEFunction && - prob.f.f isa FunctionWrappersWrappers.FunctionWrappersWrapper) - return remake(alg, chunk_size = Val{1}()) + # If prob.f.f is a FunctionWrappersWrappers from ODEFunction, need to set chunksize to 1 + + if alg_autodiff(alg) isa AutoForwardDiff && ((prob.f isa ODEFunction && + prob.f.f isa FunctionWrappersWrappers.FunctionWrappersWrapper) || + (isbitstype(T) && sizeof(T) > 24)) + return remake( + alg, autodiff = AutoForwardDiff(chunksize = 1, tag = alg_autodiff(alg).tag)) + end + + # If the autodiff alg is AutoFiniteDiff, prob.f.f isa FunctionWrappersWrapper, + # and fdtype is complex, fdtype needs to change to something not complex + if alg_autodiff(alg) isa AutoFiniteDiff + if alg_difftype(alg) == Val{:complex} && (prob.f isa ODEFunction && + prob.f.f isa FunctionWrappersWrappers.FunctionWrappersWrapper) + @warn "AutoFiniteDiff fdtype complex is not compatible with this function" + return remake(alg, autodiff = AutoFiniteDiff(fdtype = Val{:forward}())) + end + return alg end L = StaticArrayInterface.known_length(typeof(u0)) @@ -66,10 +82,14 @@ function DiffEqBase.prepare_alg( end cs = ForwardDiff.pickchunksize(x) - return remake(alg, chunk_size = Val{cs}()) + return remake(alg, + autodiff = AutoForwardDiff( + chunksize = cs)) else # statically sized cs = pick_static_chunksize(Val{L}()) - return remake(alg, chunk_size = cs) + cs = SciMLBase._unwrap_val(cs) + return remake( + alg, autodiff = AutoForwardDiff(chunksize = cs)) end end diff --git a/lib/OrdinaryDiffEqDifferentiation/src/derivative_utils.jl b/lib/OrdinaryDiffEqDifferentiation/src/derivative_utils.jl index abf994e5bc..21b23c60fa 100644 --- a/lib/OrdinaryDiffEqDifferentiation/src/derivative_utils.jl +++ b/lib/OrdinaryDiffEqDifferentiation/src/derivative_utils.jl @@ -144,7 +144,6 @@ function calc_J!(J, integrator, cache, next_step::Bool = false) f.jac(J, uprev, p, t) else @unpack du1, uf, jac_config = cache - uf.f = nlsolve_f(f, alg) uf.t = t if !(p isa DiffEqBase.NullParameters) diff --git a/lib/OrdinaryDiffEqDifferentiation/src/derivative_wrappers.jl b/lib/OrdinaryDiffEqDifferentiation/src/derivative_wrappers.jl index 626d9fad7f..3ef9cf3c4f 100644 --- a/lib/OrdinaryDiffEqDifferentiation/src/derivative_wrappers.jl +++ b/lib/OrdinaryDiffEqDifferentiation/src/derivative_wrappers.jl @@ -80,7 +80,8 @@ function derivative!(df::AbstractArray{<:Number}, f, integrator, grad_config) alg = unwrap_alg(integrator, true) tmp = length(x) # We calculate derivative for all elements in gradient - if alg_autodiff(alg) isa AutoForwardDiff + autodiff_alg = alg_autodiff(alg) + if autodiff_alg isa AutoForwardDiff T = if standardtag(alg) typeof(ForwardDiff.Tag(OrdinaryDiffEqTag(), eltype(df))) else @@ -102,7 +103,7 @@ function derivative!(df::AbstractArray{<:Number}, f, df .= first.(ForwardDiff.partials.(grad_config)) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) - elseif alg_autodiff(alg) isa AutoFiniteDiff + elseif autodiff_alg isa AutoFiniteDiff FiniteDiff.finite_difference_gradient!(df, f, x, grad_config, dir = diffdir(integrator)) fdtype = alg_difftype(alg) @@ -279,7 +280,6 @@ function build_jac_config(alg, f::F1, uf::F2, du1, uprev, u, tmp, du2) where {F1 end sparsity, colorvec = sparsity_colorvec(f, u) - if alg_autodiff(alg) isa AutoForwardDiff _chunksize = get_chunksize(alg) === Val(0) ? nothing : get_chunksize(alg) # SparseDiffEq uses different convection... T = if standardtag(alg) @@ -287,6 +287,10 @@ function build_jac_config(alg, f::F1, uf::F2, du1, uprev, u, tmp, du2) where {F1 else typeof(ForwardDiff.Tag(uf, eltype(u))) end + + if _chunksize === Val{nothing}() + _chunksize = nothing + end jac_config = ForwardColorJacCache(uf, uprev, _chunksize; colorvec = colorvec, sparsity = sparsity, tag = T) elseif alg_autodiff(alg) isa AutoFiniteDiff diff --git a/lib/OrdinaryDiffEqExponentialRK/Project.toml b/lib/OrdinaryDiffEqExponentialRK/Project.toml index 3dce2d7dd4..d4c97e0ac0 100644 --- a/lib/OrdinaryDiffEqExponentialRK/Project.toml +++ b/lib/OrdinaryDiffEqExponentialRK/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqExponentialRK" uuid = "e0540318-69ee-4070-8777-9e2de6de23de" authors = ["ParamThakkar123 "] -version = "1.1.0" +version = "1.2.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" ExponentialUtilities = "d4d017d3-3776-5f7e-afef-a10c40355c18" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" @@ -18,6 +19,7 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" ExponentialUtilities = "1.26.1" @@ -25,8 +27,8 @@ FastBroadcast = "0.3.5" LinearAlgebra = "<0.0.1, 1" LinearSolve = "2.32.0" MuladdMacro = "0.2.4" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.13" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" OrdinaryDiffEqSDIRK = "<0.0.1, 1" OrdinaryDiffEqTsit5 = "<0.0.1, 1" OrdinaryDiffEqVerner = "<0.0.1, 1" diff --git a/lib/OrdinaryDiffEqExponentialRK/src/OrdinaryDiffEqExponentialRK.jl b/lib/OrdinaryDiffEqExponentialRK/src/OrdinaryDiffEqExponentialRK.jl index 98fde5722c..6fe57c7b40 100644 --- a/lib/OrdinaryDiffEqExponentialRK/src/OrdinaryDiffEqExponentialRK.jl +++ b/lib/OrdinaryDiffEqExponentialRK/src/OrdinaryDiffEqExponentialRK.jl @@ -10,7 +10,7 @@ import OrdinaryDiffEqCore: alg_order, alg_adaptive_order, ismultistep, ExponentialAlgorithm, fsal_typeof, isdtchangeable, calculate_residuals, calculate_residuals!, full_cache, get_fsalfirstlast, - generic_solver_docstring + generic_solver_docstring, _bool_to_ADType, _process_AD_choice import OrdinaryDiffEqCore using RecursiveArrayTools using MuladdMacro, FastBroadcast @@ -20,6 +20,7 @@ using ExponentialUtilities import RecursiveArrayTools: recursivecopy! using OrdinaryDiffEqDifferentiation: build_jac_config, UJacobianWrapper, UDerivativeWrapper, calc_J, calc_J! +import ADTypes: AutoForwardDiff, AbstractADType using Reexport @reexport using DiffEqBase diff --git a/lib/OrdinaryDiffEqExponentialRK/src/algorithms.jl b/lib/OrdinaryDiffEqExponentialRK/src/algorithms.jl index 6f83541846..e2f8a13af4 100644 --- a/lib/OrdinaryDiffEqExponentialRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqExponentialRK/src/algorithms.jl @@ -32,16 +32,20 @@ for (Alg, Description, Ref) in [ krylov::Bool m::Int iop::Int + autodiff::AD end end - @eval function $Alg(; krylov = false, m = 30, iop = 0, autodiff = true, + @eval function $Alg(; krylov = false, m = 30, iop = 0, autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, chunk_size = Val{0}(), - diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), + diff_type = Val{:forward}()) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + $Alg{_unwrap_val(chunk_size), typeof(AD_choice), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(krylov, m, - iop) + iop, + AD_choice) end end @@ -72,15 +76,20 @@ for (Alg, Description, Ref) in [ OrdinaryDiffEqAdaptiveExponentialAlgorithm{CS, AD, FDT, ST, CJ} m::Int iop::Int + autodiff::AD end end - @eval function $Alg(; m = 30, iop = 0, autodiff = true, standardtag = Val{true}(), + @eval function $Alg(; + m = 30, iop = 0, autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, chunk_size = Val{0}(), - diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), + diff_type = Val{:forward}()) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + $Alg{_unwrap_val(chunk_size), typeof(AD_choice), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(m, - iop) + iop, + AD_choice) end end @@ -123,20 +132,26 @@ for (Alg, Description, Ref) in [(:Exp4, "4th order EPIRK scheme.", REF3) m = 30, iop = 0, """) + struct $Alg{CS, AD, FDT, ST, CJ} <: OrdinaryDiffEqExponentialAlgorithm{CS, AD, FDT, ST, CJ} adaptive_krylov::Bool m::Int iop::Int + autodiff::AD end end - @eval function $Alg(; adaptive_krylov = true, m = 30, iop = 0, autodiff = true, + @eval function $Alg(; + adaptive_krylov = true, m = 30, iop = 0, autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - chunk_size = Val{0}(), diff_type = Val{:forward}) - $Alg{_unwrap_val(chunk_size), _unwrap_val(autodiff), diff_type, + chunk_size = Val{0}(), diff_type = Val{:forward}()) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + $Alg{_unwrap_val(chunk_size), typeof(AD_choice), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(adaptive_krylov, m, - iop) + iop, + AD_choice) end end diff --git a/lib/OrdinaryDiffEqExtrapolation/Project.toml b/lib/OrdinaryDiffEqExtrapolation/Project.toml index 684fb1bb4e..8409e19cdd 100644 --- a/lib/OrdinaryDiffEqExtrapolation/Project.toml +++ b/lib/OrdinaryDiffEqExtrapolation/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqExtrapolation" uuid = "becaefa8-8ca2-5cf9-886d-c06f3d2bd2c4" authors = ["Chris Rackauckas ", "Yingbo Ma "] -version = "1.2.1" +version = "1.3.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" FastPower = "a4df4552-cc26-4903-aec0-212e50a0e84b" @@ -16,14 +17,15 @@ RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" FastPower = "1" LinearSolve = "2.32.0" MuladdMacro = "0.2.4" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.13" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" Polyester = "0.7.16" Random = "<0.0.1, 1" RecursiveArrayTools = "3.27.0" diff --git a/lib/OrdinaryDiffEqExtrapolation/src/OrdinaryDiffEqExtrapolation.jl b/lib/OrdinaryDiffEqExtrapolation/src/OrdinaryDiffEqExtrapolation.jl index 3482022699..81cda321b9 100644 --- a/lib/OrdinaryDiffEqExtrapolation/src/OrdinaryDiffEqExtrapolation.jl +++ b/lib/OrdinaryDiffEqExtrapolation/src/OrdinaryDiffEqExtrapolation.jl @@ -17,7 +17,7 @@ import OrdinaryDiffEqCore: alg_order, alg_maximum_order, get_current_adaptive_or constvalue, PolyesterThreads, Sequential, BaseThreads, _digest_beta1_beta2, timedepentdtmin, _unwrap_val, _reshape, _vec, get_fsalfirstlast, generic_solver_docstring, - differentiation_rk_docstring + differentiation_rk_docstring, _bool_to_ADType, _process_AD_choice using DiffEqBase, FastBroadcast, Polyester, MuladdMacro, RecursiveArrayTools, LinearSolve import OrdinaryDiffEqCore import FastPower @@ -25,6 +25,7 @@ import OrdinaryDiffEqDifferentiation: TimeDerivativeWrapper, UDerivativeWrapper, WOperator, TimeGradientWrapper, UJacobianWrapper, build_grad_config, build_jac_config, calc_J!, jacobian2W!, dolinsolve +import ADTypes: AutoForwardDiff, AbstractADType using Reexport @reexport using DiffEqBase diff --git a/lib/OrdinaryDiffEqExtrapolation/src/algorithms.jl b/lib/OrdinaryDiffEqExtrapolation/src/algorithms.jl index 205e8e1f3d..cc53871818 100644 --- a/lib/OrdinaryDiffEqExtrapolation/src/algorithms.jl +++ b/lib/OrdinaryDiffEqExtrapolation/src/algorithms.jl @@ -64,14 +64,17 @@ struct ImplicitEulerExtrapolation{CS, AD, F, P, FDT, ST, CJ, TO} <: init_order::Int threading::TO sequence::Symbol # Name of the subdividing sequence + autodiff::AD end -function ImplicitEulerExtrapolation(; chunk_size = Val{0}(), autodiff = true, +function ImplicitEulerExtrapolation(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = nothing, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, max_order = 12, min_order = 3, init_order = 5, threading = false, sequence = :harmonic) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + linsolve = (linsolve === nothing && (threading == true || threading isa PolyesterThreads)) ? RFLUFactorization(; thread = Val(false)) : linsolve @@ -99,12 +102,12 @@ Initial order: " * lpad(init_order, 2, " ") * " --> " * lpad(init_order, 2, " ") :$(sequence) --> :harmonic" sequence = :harmonic end - ImplicitEulerExtrapolation{_unwrap_val(chunk_size), _unwrap_val(autodiff), + ImplicitEulerExtrapolation{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(threading)}(linsolve, precs, max_order, min_order, init_order, - threading, sequence) + threading, sequence, AD_choice) end @doc generic_solver_docstring("Midpoint extrapolation using Barycentric coordinates.", @@ -204,13 +207,17 @@ struct ImplicitDeuflhardExtrapolation{CS, AD, F, P, FDT, ST, CJ, TO} <: max_order::Int # Maximal extrapolation order sequence::Symbol # Name of the subdividing sequence threading::TO + autodiff::AD end -function ImplicitDeuflhardExtrapolation(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ImplicitDeuflhardExtrapolation(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, linsolve = nothing, precs = DEFAULT_PRECS, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), min_order = 1, init_order = 5, max_order = 10, sequence = :harmonic, threading = false) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + # Enforce 1 <= min_order <= init_order <= max_order: min_order = max(1, min_order) init_order = max(min_order, init_order) @@ -242,12 +249,12 @@ Initial order: " * lpad(init_order, 2, " ") * " --> " * lpad(init_order, 2, " ") end # Initialize algorithm - ImplicitDeuflhardExtrapolation{_unwrap_val(chunk_size), _unwrap_val(autodiff), + ImplicitDeuflhardExtrapolation{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(threading)}(linsolve, precs, min_order, init_order, max_order, - sequence, threading) + sequence, threading, AD_choice) end @doc generic_solver_docstring("Midpoint extrapolation using Barycentric coordinates, @@ -351,15 +358,18 @@ struct ImplicitHairerWannerExtrapolation{CS, AD, F, P, FDT, ST, CJ, TO} <: max_order::Int # Maximal extrapolation order sequence::Symbol # Name of the subdividing sequence threading::TO + autodiff::AD end -function ImplicitHairerWannerExtrapolation(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ImplicitHairerWannerExtrapolation(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, linsolve = nothing, precs = DEFAULT_PRECS, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), min_order = 2, init_order = 5, max_order = 10, sequence = :harmonic, threading = false) + # Enforce 2 <= min_order # and min_order + 1 <= init_order <= max_order - 1: min_order = max(2, min_order) @@ -390,13 +400,14 @@ Initial order: " * lpad(init_order, 2, " ") * " --> " * lpad(init_order, 2, " ") sequence = :harmonic end + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) # Initialize algorithm - ImplicitHairerWannerExtrapolation{_unwrap_val(chunk_size), _unwrap_val(autodiff), + ImplicitHairerWannerExtrapolation{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(threading)}(linsolve, precs, min_order, init_order, - max_order, sequence, threading) + max_order, sequence, threading, AD_choice) end @doc differentiation_rk_docstring("Euler extrapolation using Barycentric coordinates, @@ -430,14 +441,15 @@ struct ImplicitEulerBarycentricExtrapolation{CS, AD, F, P, FDT, ST, CJ, TO} <: sequence::Symbol # Name of the subdividing sequence threading::TO sequence_factor::Int + autodiff::AD end function ImplicitEulerBarycentricExtrapolation(; chunk_size = Val{0}(), - autodiff = Val{true}(), + autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, linsolve = nothing, precs = DEFAULT_PRECS, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), min_order = 3, init_order = 5, max_order = 12, sequence = :harmonic, threading = false, sequence_factor = 2) @@ -471,8 +483,9 @@ Initial order: " * lpad(init_order, 2, " ") * " --> " * lpad(init_order, 2, " ") sequence = :harmonic end + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) # Initialize algorithm - ImplicitEulerBarycentricExtrapolation{_unwrap_val(chunk_size), _unwrap_val(autodiff), + ImplicitEulerBarycentricExtrapolation{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(threading)}(linsolve, @@ -482,5 +495,6 @@ Initial order: " * lpad(init_order, 2, " ") * " --> " * lpad(init_order, 2, " ") max_order, sequence, threading, - sequence_factor) + sequence_factor, + AD_choice) end diff --git a/lib/OrdinaryDiffEqExtrapolation/src/controllers.jl b/lib/OrdinaryDiffEqExtrapolation/src/controllers.jl index a6ae7ea315..c50fddc82e 100644 --- a/lib/OrdinaryDiffEqExtrapolation/src/controllers.jl +++ b/lib/OrdinaryDiffEqExtrapolation/src/controllers.jl @@ -34,7 +34,8 @@ function stepsize_controller_internal!(integrator, integrator.opts.gamma = FastPower.fastpower(typeof(integrator.opts.gamma)(1 // 4), controller.beta1) # Compute new stepsize scaling - qtmp = FastPower.fastpower(integrator.EEst, controller.beta1) / integrator.opts.gamma + qtmp = FastPower.fastpower(integrator.EEst, controller.beta1) / + integrator.opts.gamma @fastmath q = max(inv(integrator.opts.qmax), min(inv(integrator.opts.qmin), qtmp)) end integrator.cache.Q[integrator.cache.n_curr - alg.min_order + 1] = q @@ -60,7 +61,8 @@ function stepsize_predictor!(integrator, integrator.opts.gamma = FastPower.fastpower(typeof(integrator.opts.gamma)(1 // 4), controller.beta1) # Compute new stepsize scaling - qtmp = EEst * FastPower.fastpower(FastPower.fastpower(tol, (1.0 - s_curr / s_new)), + qtmp = EEst * + FastPower.fastpower(FastPower.fastpower(tol, (1.0 - s_curr / s_new)), controller.beta1) / integrator.opts.gamma @fastmath q = max(inv(integrator.opts.qmax), min(inv(integrator.opts.qmin), qtmp)) end diff --git a/lib/OrdinaryDiffEqFIRK/Project.toml b/lib/OrdinaryDiffEqFIRK/Project.toml index 62fc014d3c..41374194f1 100644 --- a/lib/OrdinaryDiffEqFIRK/Project.toml +++ b/lib/OrdinaryDiffEqFIRK/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqFIRK" uuid = "5960d6e9-dd7a-4743-88e7-cf307b64f125" authors = ["ParamThakkar123 "] -version = "1.5.0" +version = "1.6.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" @@ -14,12 +15,14 @@ MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" OrdinaryDiffEqCore = "bbf590c4-e513-4bbe-9b18-05decba2e5d8" OrdinaryDiffEqDifferentiation = "4302a76b-040a-498a-8c04-15b101fed76b" OrdinaryDiffEqNonlinearSolve = "127b3ac7-2247-4354-8eb6-78cf4e7c58e8" +Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" @@ -29,9 +32,10 @@ LinearAlgebra = "<0.0.1, 1" LinearSolve = "2.32.0" MuladdMacro = "0.2.4" ODEProblemLibrary = "0.1.8" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.14" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" OrdinaryDiffEqNonlinearSolve = "<0.0.1, 1" +Polyester = "0.7.16" Random = "<0.0.1, 1" RecursiveArrayTools = "3.27.0" Reexport = "1.2.2" diff --git a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl index 5817abd9b7..c4c9501109 100644 --- a/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl +++ b/lib/OrdinaryDiffEqFIRK/src/OrdinaryDiffEqFIRK.jl @@ -6,8 +6,9 @@ import OrdinaryDiffEqCore: alg_order, calculate_residuals!, OrdinaryDiffEqAlgorithm, OrdinaryDiffEqNewtonAdaptiveAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache, OrdinaryDiffEqAdaptiveAlgorithm, CompiledFloats, uses_uprev, - alg_cache, _vec, _reshape, @cache, isfsal, full_cache, - constvalue, _unwrap_val, + alg_cache, _vec, _reshape, @cache, @threaded, isthreaded, + PolyesterThreads, + isfsal, full_cache, constvalue, _unwrap_val, differentiation_rk_docstring, trivial_limiter!, _ode_interpolant!, _ode_addsteps!, AbstractController, qmax_default, alg_adaptive_order, DEFAULT_PRECS, @@ -16,8 +17,10 @@ import OrdinaryDiffEqCore: alg_order, calculate_residuals!, PredictiveController, alg_can_repeat_jac, NewtonAlgorithm, fac_default_gamma, get_current_adaptive_order, get_fsalfirstlast, - isfirk, generic_solver_docstring -using MuladdMacro, DiffEqBase, RecursiveArrayTools + isfirk, generic_solver_docstring, _bool_to_ADType, + _process_AD_choice +using MuladdMacro, DiffEqBase, RecursiveArrayTools, Polyester +isfirk, generic_solver_docstring using SciMLOperators: AbstractSciMLOperator using LinearAlgebra: I, UniformScaling, mul!, lu import LinearSolve @@ -31,6 +34,7 @@ using OrdinaryDiffEqDifferentiation: UJacobianWrapper, build_J_W, build_jac_conf using OrdinaryDiffEqNonlinearSolve: du_alias_or_new, Convergence, FastConvergence, NLStatus, VerySlowConvergence, Divergence, get_new_W_γdt_cutoff +import ADTypes: AutoForwardDiff, AbstractADType using Reexport @reexport using DiffEqBase diff --git a/lib/OrdinaryDiffEqFIRK/src/algorithms.jl b/lib/OrdinaryDiffEqFIRK/src/algorithms.jl index e98389ec7c..0fbca63150 100644 --- a/lib/OrdinaryDiffEqFIRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqFIRK/src/algorithms.jl @@ -37,17 +37,20 @@ struct RadauIIA3{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: new_W_γdt_cutoff::C2 controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function RadauIIA3(; chunk_size = Val{0}(), autodiff = Val{true}(), +function RadauIIA3(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + RadauIIA3{_unwrap_val(chunk_size), typeof(AD_choice), 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, @@ -58,7 +61,8 @@ function RadauIIA3(; chunk_size = Val{0}(), autodiff = Val{true}(), fast_convergence_cutoff, new_W_γdt_cutoff, controller, - step_limiter!) + step_limiter!, + AD_choice) end @doc differentiation_rk_docstring( @@ -81,17 +85,20 @@ struct RadauIIA5{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: new_W_γdt_cutoff::C2 controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function RadauIIA5(; chunk_size = Val{0}(), autodiff = Val{true}(), +function RadauIIA5(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + RadauIIA5{_unwrap_val(chunk_size), typeof(AD_choice), 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, @@ -103,7 +110,8 @@ function RadauIIA5(; chunk_size = Val{0}(), autodiff = Val{true}(), fast_convergence_cutoff, new_W_γdt_cutoff, controller, - step_limiter!) + step_limiter!, + AD_choice) end @doc differentiation_rk_docstring( @@ -126,17 +134,20 @@ struct RadauIIA9{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter} <: new_W_γdt_cutoff::C2 controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function RadauIIA9(; chunk_size = Val{0}(), autodiff = Val{true}(), +function RadauIIA9(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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!) - RadauIIA9{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + RadauIIA9{_unwrap_val(chunk_size), typeof(AD_choice), 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, @@ -148,45 +159,50 @@ function RadauIIA9(; chunk_size = Val{0}(), autodiff = Val{true}(), fast_convergence_cutoff, new_W_γdt_cutoff, controller, - step_limiter!) + step_limiter!, + AD_choice) end -struct AdaptiveRadau{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 - min_order::Int - max_order::Int +struct AdaptiveRadau{CS, AD, F, P, FDT, ST, CJ, Tol, C1, C2, StepLimiter, TO} <: + 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 + min_order::Int + max_order::Int + threading::TO + autodiff::AD end -function AdaptiveRadau(; chunk_size = Val{0}(), autodiff = Val{true}(), - standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, min_order = 5, max_order = 13, - 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!) - AdaptiveRadau{_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!, min_order, max_order) -end +function AdaptiveRadau(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), + standardtag = Val{true}(), concrete_jac = nothing, + diff_type = Val{:forward}, min_order = 5, max_order = 13, threading = false, + 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!) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + AdaptiveRadau{_unwrap_val(chunk_size), typeof(AD_choice), 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!), typeof(threading)}(linsolve, + precs, + smooth_est, + extrapolant, + κ, + maxiters, + fast_convergence_cutoff, + new_W_γdt_cutoff, + controller, + step_limiter!, min_order, max_order, threading, + AD_choice) +end diff --git a/lib/OrdinaryDiffEqFIRK/src/controllers.jl b/lib/OrdinaryDiffEqFIRK/src/controllers.jl index 3849d8114c..637dba9dda 100644 --- a/lib/OrdinaryDiffEqFIRK/src/controllers.jl +++ b/lib/OrdinaryDiffEqFIRK/src/controllers.jl @@ -1,8 +1,9 @@ -function step_accept_controller!(integrator, controller::PredictiveController, alg::AdaptiveRadau, q) +function step_accept_controller!( + integrator, controller::PredictiveController, alg::AdaptiveRadau, q) @unpack qmin, qmax, gamma, qsteady_min, qsteady_max = integrator.opts @unpack cache = integrator - @unpack num_stages, step, iter, hist_iter = cache - + @unpack num_stages, step, iter, hist_iter, index = cache + EEst = DiffEqBase.value(integrator.EEst) if integrator.success_iter > 0 @@ -25,12 +26,15 @@ function step_accept_controller!(integrator, controller::PredictiveController, a max_stages = (alg.max_order - 1) ÷ 4 * 2 + 1 min_stages = (alg.min_order - 1) ÷ 4 * 2 + 1 if (step > 10) - if (hist_iter < 2.6 && num_stages <= max_stages) + if (hist_iter < 2.6 && num_stages < max_stages) cache.num_stages += 2 + cache.index += 1 cache.step = 1 cache.hist_iter = iter - elseif ((hist_iter > 8 || cache.status == VerySlowConvergence || cache.status == Divergence) && num_stages >= min_stages) - cache.num_stages -= 2 + elseif ((hist_iter > 8 || cache.status == VerySlowConvergence || + cache.status == Divergence) && num_stages > min_stages) + cache.num_stages -= 2 + cache.index -= 1 cache.step = 1 cache.hist_iter = iter end @@ -38,9 +42,10 @@ function step_accept_controller!(integrator, controller::PredictiveController, a return integrator.dt / qacc end -function step_reject_controller!(integrator, controller::PredictiveController, alg::AdaptiveRadau) +function step_reject_controller!( + integrator, controller::PredictiveController, alg::AdaptiveRadau) @unpack dt, success_iter, qold = integrator - @unpack cache = integrator + @unpack cache = integrator @unpack num_stages, step, iter, hist_iter = cache integrator.dt = success_iter == 0 ? 0.1 * dt : dt / qold cache.step = step + 1 @@ -48,11 +53,12 @@ function step_reject_controller!(integrator, controller::PredictiveController, a cache.hist_iter = hist_iter min_stages = (alg.min_order - 1) ÷ 4 * 2 + 1 if (step > 10) - if ((hist_iter > 8 || cache.status == VerySlowConvergence || cache.status == Divergence) && num_stages >= min_stages) - cache.num_stages -= 2 + if ((hist_iter > 8 || cache.status == VerySlowConvergence || + cache.status == Divergence) && num_stages > min_stages) + cache.num_stages -= 2 + cache.index -= 1 cache.step = 1 cache.hist_iter = iter end end end - diff --git a/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl b/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl index fb773cf4b0..db425773df 100644 --- a/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl +++ b/lib/OrdinaryDiffEqFIRK/src/firk_caches.jl @@ -483,7 +483,7 @@ function alg_cache(alg::RadauIIA9, u, rate_prototype, ::Type{uEltypeNoUnits}, end mutable struct AdaptiveRadauConstantCache{F, Tab, Tol, Dt, U, JType} <: - OrdinaryDiffEqConstantCache + OrdinaryDiffEqConstantCache uf::F tabs::Vector{Tab} κ::Tol @@ -497,6 +497,7 @@ mutable struct AdaptiveRadauConstantCache{F, Tab, Tol, Dt, U, JType} <: num_stages::Int step::Int hist_iter::Float64 + index::Int end function alg_cache(alg::AdaptiveRadau, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -508,33 +509,32 @@ function alg_cache(alg::AdaptiveRadau, u, rate_prototype, ::Type{uEltypeNoUnits} max_order = alg.max_order min_order = alg.min_order - max = (max_order - 1) ÷ 4 * 2 + 1 - min = (min_order - 1) ÷ 4 * 2 + 1 + max_stages = (max_order - 1) ÷ 4 * 2 + 1 + min_stages = (min_order - 1) ÷ 4 * 2 + 1 if (alg.min_order < 5) error("min_order choice $min_order below 5 is not compatible with the algorithm") - elseif (max < min) + elseif (max_stages < min_stages) error("max_order $max_order is below min_order $min_order") end - num_stages = min + num_stages = min_stages - tabs = [RadauIIATableau5(uToltype, constvalue(tTypeNoUnits)), RadauIIATableau9(uToltype, constvalue(tTypeNoUnits)), RadauIIATableau13(uToltype, constvalue(tTypeNoUnits))] - i = 9 - while i <= max - push!(tabs, RadauIIATableau(uToltype, constvalue(tTypeNoUnits), i)) - i += 2 - end - cont = Vector{typeof(u)}(undef, max) - for i in 1:max + tabs = [RadauIIATableau(uToltype, constvalue(tTypeNoUnits), i) + for i in min_stages:2:max_stages] + cont = Vector{typeof(u)}(undef, max_stages) + for i in 1:max_stages cont[i] = zero(u) end + index = 1 + κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) J = false .* _vec(rate_prototype) .* _vec(rate_prototype)' AdaptiveRadauConstantCache(uf, tabs, κ, one(uToltype), 10000, cont, dt, dt, - Convergence, J, num_stages, 1, 0.0) + Convergence, J, num_stages, 1, 0.0, index) end -mutable struct AdaptiveRadauCache{uType, cuType, tType, uNoUnitsType, rateType, JType, W1Type, W2Type, +mutable struct AdaptiveRadauCache{ + uType, cuType, tType, uNoUnitsType, rateType, JType, W1Type, W2Type, UF, JC, F1, F2, Tab, Tol, Dt, rTol, aTol, StepLimiter} <: FIRKMutableCache u::uType @@ -550,7 +550,7 @@ mutable struct AdaptiveRadauCache{uType, cuType, tType, uNoUnitsType, rateType, cubuff::Vector{cuType} dw::Vector{uType} cont::Vector{uType} - derivatives:: Matrix{uType} + derivatives::Matrix{uType} du1::rateType fsalfirst::rateType ks::Vector{rateType} @@ -578,6 +578,7 @@ mutable struct AdaptiveRadauCache{uType, cuType, tType, uNoUnitsType, rateType, num_stages::Int step::Int hist_iter::Float64 + index::Int end function alg_cache(alg::AdaptiveRadau, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -589,56 +590,54 @@ function alg_cache(alg::AdaptiveRadau, u, rate_prototype, ::Type{uEltypeNoUnits} max_order = alg.max_order min_order = alg.min_order - max = (max_order - 1) ÷ 4 * 2 + 1 - min = (min_order - 1) ÷ 4 * 2 + 1 + max_stages = (max_order - 1) ÷ 4 * 2 + 1 + min_stages = (min_order - 1) ÷ 4 * 2 + 1 if (alg.min_order < 5) error("min_order choice $min_order below 5 is not compatible with the algorithm") - elseif (max < min) + elseif (max_stages < min_stages) error("max_order $max_order is below min_order $min_order") end - num_stages = min + num_stages = min_stages - tabs = [RadauIIATableau5(uToltype, constvalue(tTypeNoUnits)), RadauIIATableau9(uToltype, constvalue(tTypeNoUnits)), RadauIIATableau13(uToltype, constvalue(tTypeNoUnits))] - i = 9 - while i <= max - push!(tabs, RadauIIATableau(uToltype, constvalue(tTypeNoUnits), i)) - i += 2 - end + tabs = [RadauIIATableau(uToltype, constvalue(tTypeNoUnits), i) + for i in min_stages:2:max_stages] + + index = 1 κ = alg.κ !== nothing ? convert(uToltype, alg.κ) : convert(uToltype, 1 // 100) - z = Vector{typeof(u)}(undef, max) - w = Vector{typeof(u)}(undef, max) - for i in 1 : max + z = Vector{typeof(u)}(undef, max_stages) + w = Vector{typeof(u)}(undef, max_stages) + for i in 1:max_stages z[i] = zero(u) w[i] = zero(u) end - αdt = [zero(t) for i in 1:max] - βdt = [zero(t) for i in 1:max] - c_prime = Vector{typeof(t)}(undef, max) #time stepping - for i in 1 : max + αdt = [zero(t) for i in 1:max_stages] + βdt = [zero(t) for i in 1:max_stages] + c_prime = Vector{typeof(t)}(undef, max_stages) #time stepping + for i in 1:max_stages c_prime[i] = zero(t) end dw1 = zero(u) ubuff = zero(u) - dw2 = [similar(u, Complex{eltype(u)}) for _ in 1 : (max - 1) ÷ 2] + dw2 = [similar(u, Complex{eltype(u)}) for _ in 1:((max_stages - 1) ÷ 2)] recursivefill!.(dw2, false) - cubuff = [similar(u, Complex{eltype(u)}) for _ in 1 : (max - 1) ÷ 2] + cubuff = [similar(u, Complex{eltype(u)}) for _ in 1:((max_stages - 1) ÷ 2)] recursivefill!.(cubuff, false) - dw = [zero(u) for i in 1 : max] + dw = [zero(u) for i in 1:max_stages] - cont = [zero(u) for i in 1:max] + cont = [zero(u) for i in 1:max_stages] - derivatives = Matrix{typeof(u)}(undef, max, max) - for i in 1 : max, j in 1 : max + derivatives = Matrix{typeof(u)}(undef, max_stages, max_stages) + for i in 1:max_stages, j in 1:max_stages derivatives[i, j] = zero(u) end fsalfirst = zero(rate_prototype) - fw = [zero(rate_prototype) for i in 1 : max] - ks = [zero(rate_prototype) for i in 1 : max] + fw = [zero(rate_prototype) for i in 1:max_stages] + ks = [zero(rate_prototype) for i in 1:max_stages] k = ks[1] @@ -647,7 +646,7 @@ function alg_cache(alg::AdaptiveRadau, u, rate_prototype, ::Type{uEltypeNoUnits} error("Non-concrete Jacobian not yet supported by AdaptiveRadau.") end - W2 = [similar(J, Complex{eltype(W1)}) for _ in 1 : (max - 1) ÷ 2] + W2 = [similar(J, Complex{eltype(W1)}) for _ in 1:((max_stages - 1) ÷ 2)] recursivefill!.(W2, false) du1 = zero(rate_prototype) @@ -663,9 +662,10 @@ function alg_cache(alg::AdaptiveRadau, u, rate_prototype, ::Type{uEltypeNoUnits} linsolve1 = init(linprob, alg.linsolve, alias_A = true, alias_b = true, assumptions = LinearSolve.OperatorAssumptions(true)) - linsolve2 = [ - init(LinearProblem(W2[i], _vec(cubuff[i]); u0 = _vec(dw2[i])), alg.linsolve, alias_A = true, alias_b = true, - assumptions = LinearSolve.OperatorAssumptions(true)) for i in 1 : (max - 1) ÷ 2] + linsolve2 = [init(LinearProblem(W2[i], _vec(cubuff[i]); u0 = _vec(dw2[i])), + alg.linsolve, alias_A = true, alias_b = true, + assumptions = LinearSolve.OperatorAssumptions(true)) + for i in 1:((max_stages - 1) ÷ 2)] rtol = reltol isa Number ? reltol : zero(reltol) atol = reltol isa Number ? reltol : zero(reltol) @@ -677,6 +677,5 @@ function alg_cache(alg::AdaptiveRadau, u, rate_prototype, ::Type{uEltypeNoUnits} uf, tabs, κ, one(uToltype), 10000, tmp, atmp, jac_config, linsolve1, linsolve2, rtol, atol, dt, dt, - Convergence, alg.step_limiter!, num_stages, 1, 0.0) + Convergence, alg.step_limiter!, num_stages, 1, 0.0, index) end - diff --git a/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl b/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl index 2058c4fb15..5bfaafb2ef 100644 --- a/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl +++ b/lib/OrdinaryDiffEqFIRK/src/firk_perform_step.jl @@ -26,7 +26,9 @@ function do_newW(integrator, nlsolver, new_jac, W_dt)::Bool # for FIRK return !smallstepchange end -function initialize!(integrator, cache::Union{RadauIIA3ConstantCache, RadauIIA5ConstantCache, RadauIIA9ConstantCache,AdaptiveRadauConstantCache}) +function initialize!(integrator, + cache::Union{RadauIIA3ConstantCache, RadauIIA5ConstantCache, + RadauIIA9ConstantCache, AdaptiveRadauConstantCache}) integrator.kshortsize = 2 integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) integrator.fsalfirst = integrator.f(integrator.uprev, integrator.p, integrator.t) # Pre-start fsal @@ -110,7 +112,6 @@ function initialize!(integrator, cache::AdaptiveRadauCache) 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 @@ -838,24 +839,24 @@ end c3′ = c3 * c5′ c4′ = c4 * c5′ z1 = @.. c1′ * (cont1 + - (c1′-c4m1) * (cont2 + - (c1′ - c3m1) * (cont3 + - (c1′ - c2m1) * (cont4 + (c1′ - c1m1) * cont5)))) + (c1′ - c4m1) * (cont2 + + (c1′ - c3m1) * (cont3 + + (c1′ - c2m1) * (cont4 + (c1′ - c1m1) * cont5)))) z2 = @.. c2′ * (cont1 + - (c2′-c4m1) * (cont2 + - (c2′ - c3m1) * (cont3 + - (c2′ - c2m1) * (cont4 + (c2′ - c1m1) * cont5)))) + (c2′ - c4m1) * (cont2 + + (c2′ - c3m1) * (cont3 + + (c2′ - c2m1) * (cont4 + (c2′ - c1m1) * cont5)))) z3 = @.. c3′ * (cont1 + - (c3′-c4m1) * (cont2 + - (c3′ - c3m1) * (cont3 + - (c3′ - c2m1) * (cont4 + (c3′ - c1m1) * cont5)))) + (c3′ - c4m1) * (cont2 + + (c3′ - c3m1) * (cont3 + + (c3′ - c2m1) * (cont4 + (c3′ - c1m1) * cont5)))) z4 = @.. c4′ * (cont1 + - (c4′-c4m1) * (cont2 + - (c4′ - c3m1) * (cont3 + - (c4′ - c2m1) * (cont4 + (c4′ - c1m1) * cont5)))) + (c4′ - c4m1) * (cont2 + + (c4′ - c3m1) * (cont3 + + (c4′ - c2m1) * (cont4 + (c4′ - c1m1) * cont5)))) z5 = @.. c5′ * (cont1 + - (c5′-c4m1) * (cont2 + - (c5′ - c3m1) * (cont3 + (c5′ - c2m1) * (cont4 + (c5′ - c1m1) * cont5)))) + (c5′ - c4m1) * (cont2 + + (c5′ - c3m1) * (cont3 + (c5′ - c2m1) * (cont4 + (c5′ - c1m1) * cont5)))) w1 = @.. broadcast=false TI11*z1+TI12*z2+TI13*z3+TI14*z4+TI15*z5 w2 = @.. broadcast=false TI21*z1+TI22*z2+TI23*z3+TI24*z4+TI25*z5 w3 = @.. broadcast=false TI31*z1+TI32*z2+TI33*z3+TI34*z4+TI35*z5 @@ -1088,29 +1089,29 @@ end c3′ = c3 * c5′ c4′ = c4 * c5′ @.. z1 = c1′ * (cont1 + - (c1′-c4m1) * (cont2 + - (c1′ - c3m1) * (cont3 + - (c1′ - c2m1) * (cont4 + (c1′ - c1m1) * cont5)))) + (c1′ - c4m1) * (cont2 + + (c1′ - c3m1) * (cont3 + + (c1′ - c2m1) * (cont4 + (c1′ - c1m1) * cont5)))) @.. z2 = c2′ * (cont1 + - (c2′-c4m1) * (cont2 + - (c2′ - c3m1) * (cont3 + - (c2′ - c2m1) * (cont4 + (c2′ - c1m1) * cont5)))) + (c2′ - c4m1) * (cont2 + + (c2′ - c3m1) * (cont3 + + (c2′ - c2m1) * (cont4 + (c2′ - c1m1) * cont5)))) @.. z3 = c3′ * (cont1 + - (c3′-c4m1) * (cont2 + - (c3′ - c3m1) * (cont3 + - (c3′ - c2m1) * (cont4 + (c3′ - c1m1) * cont5)))) + (c3′ - c4m1) * (cont2 + + (c3′ - c3m1) * (cont3 + + (c3′ - c2m1) * (cont4 + (c3′ - c1m1) * cont5)))) @.. z4 = c4′ * (cont1 + - (c4′-c4m1) * (cont2 + - (c4′ - c3m1) * (cont3 + - (c4′ - c2m1) * (cont4 + (c4′ - c1m1) * cont5)))) + (c4′ - c4m1) * (cont2 + + (c4′ - c3m1) * (cont3 + + (c4′ - c2m1) * (cont4 + (c4′ - c1m1) * cont5)))) @.. z5 = c5′ * (cont1 + - (c5′-c4m1) * (cont2 + - (c5′ - c3m1) * (cont3 + (c5′ - c2m1) * (cont4 + (c5′ - c1m1) * cont5)))) - @.. w1 = TI11*z1+TI12*z2+TI13*z3+TI14*z4+TI15*z5 - @.. w2 = TI21*z1+TI22*z2+TI23*z3+TI24*z4+TI25*z5 - @.. w3 = TI31*z1+TI32*z2+TI33*z3+TI34*z4+TI35*z5 - @.. w4 = TI41*z1+TI42*z2+TI43*z3+TI44*z4+TI45*z5 - @.. w5 = TI51*z1+TI52*z2+TI53*z3+TI54*z4+TI55*z5 + (c5′ - c4m1) * (cont2 + + (c5′ - c3m1) * (cont3 + (c5′ - c2m1) * (cont4 + (c5′ - c1m1) * cont5)))) + @.. w1 = TI11 * z1 + TI12 * z2 + TI13 * z3 + TI14 * z4 + TI15 * z5 + @.. w2 = TI21 * z1 + TI22 * z2 + TI23 * z3 + TI24 * z4 + TI25 * z5 + @.. w3 = TI31 * z1 + TI32 * z2 + TI33 * z3 + TI34 * z4 + TI35 * z5 + @.. w4 = TI41 * z1 + TI42 * z2 + TI43 * z3 + TI44 * z4 + TI45 * z5 + @.. w5 = TI51 * z1 + TI52 * z2 + TI53 * z3 + TI54 * z4 + TI55 * z5 end # Newton iteration @@ -1182,9 +1183,11 @@ end linsolve1 = cache.linsolve1 if needfactor - linres1 = dolinsolve(integrator, linsolve1; A = W1, b = _vec(ubuff), linu = _vec(dw1)) + 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)) + linres1 = dolinsolve( + integrator, linsolve1; A = nothing, b = _vec(ubuff), linu = _vec(dw1)) end cache.linsolve1 = linres1.cache @@ -1195,9 +1198,11 @@ end linsolve2 = cache.linsolve2 if needfactor - linres2 = dolinsolve(integrator, linsolve2; A = W2, b = _vec(cubuff1), linu = _vec(dw23)) + linres2 = dolinsolve( + integrator, linsolve2; A = W2, b = _vec(cubuff1), linu = _vec(dw23)) else - linres2 = dolinsolve(integrator, linsolve2; A = nothing, b = _vec(cubuff1), linu = _vec(dw23)) + linres2 = dolinsolve( + integrator, linsolve2; A = nothing, b = _vec(cubuff1), linu = _vec(dw23)) end cache.linsolve2 = linres2.cache @@ -1208,9 +1213,11 @@ end linsolve3 = cache.linsolve3 if needfactor - linres3 = dolinsolve(integrator, linsolve3; A = W3, b = _vec(cubuff2), linu = _vec(dw45)) + linres3 = dolinsolve( + integrator, linsolve3; A = W3, b = _vec(cubuff2), linu = _vec(dw45)) else - linres3 = dolinsolve(integrator, linsolve3; A = nothing, b = _vec(cubuff2), linu = _vec(dw45)) + linres3 = dolinsolve( + integrator, linsolve3; A = nothing, b = _vec(cubuff2), linu = _vec(dw45)) end cache.linsolve3 = linres3.cache @@ -1352,10 +1359,10 @@ end end @muladd function perform_step!(integrator, cache::AdaptiveRadauConstantCache, - repeat_step = false) + repeat_step = false) @unpack t, dt, uprev, u, f, p = integrator - @unpack tabs, num_stages = cache - tab = tabs[(num_stages - 1) ÷ 2] + @unpack tabs, num_stages, index = cache + tab = tabs[index] @unpack T, TI, γ, α, β, c, e = tab @unpack κ, cont = cache @unpack internalnorm, abstol, reltol, adaptive = integrator.opts @@ -1377,14 +1384,14 @@ end LU1 = lu(-γdt * mass_matrix + J) tmp = lu(-(αdt[1] + βdt[1] * im) * mass_matrix + J) end - LU2 = Vector{typeof(tmp)}(undef, (num_stages - 1) ÷ 2) + LU2 = Vector{typeof(tmp)}(undef, (num_stages - 1) ÷ 2) LU2[1] = tmp if u isa Number - for i in 2 : (num_stages - 1) ÷ 2 + for i in 2:((num_stages - 1) ÷ 2) LU2[i] = -(αdt[i] + βdt[i] * im) * mass_matrix + J end else - for i in 2 : (num_stages - 1) ÷ 2 + for i in 2:((num_stages - 1) ÷ 2) LU2[i] = lu(-(αdt[i] + βdt[i] * im) * mass_matrix + J) end end @@ -1394,7 +1401,7 @@ end w = Vector{typeof(u)}(undef, num_stages) if integrator.iter == 1 || integrator.u_modified || alg.extrapolant == :constant cache.dtprev = one(cache.dtprev) - for i in 1 : num_stages + for i in 1:num_stages z[i] = @.. map(zero, u) w[i] = @.. map(zero, u) cache.cont[i] = @.. map(zero, u) @@ -1402,10 +1409,10 @@ end else c_prime = Vector{typeof(dt)}(undef, num_stages) #time stepping c_prime[num_stages] = dt / cache.dtprev - for i in 1 : num_stages - 1 + for i in 1:(num_stages - 1) c_prime[i] = c[i] * c_prime[num_stages] end - for i in 1 : num_stages # collocation polynomial + for i in 1:num_stages # collocation polynomial z[i] = @.. cont[num_stages - 1] + cont[num_stages] * (c_prime[i] - c[1] + 1) j = num_stages - 2 while j > 0 @@ -1418,7 +1425,7 @@ end for i in 1:num_stages w[i] = @.. zero(u) for j in 1:num_stages - w[i] = @.. w[i] + TI[i,j] * z[j] + w[i] = @.. w[i] + TI[i, j] * z[j] end end end @@ -1434,23 +1441,23 @@ end # evaluate function #ff = Vector{typeof(u)}(undef, num_stages) - for i in 1 : num_stages + for i in 1:num_stages z[i] = f(uprev + z[i], p, t + c[i] * dt) end OrdinaryDiffEqCore.increment_nf!(integrator.stats, num_stages) #fw = TI * ff fw = Vector{typeof(u)}(undef, num_stages) - for i in 1 : num_stages + for i in 1:num_stages fw[i] = @.. zero(u) for j in 1:num_stages - fw[i] = @.. fw[i] + TI[i,j] * z[j] + fw[i] = @.. fw[i] + TI[i, j] * z[j] end end #Mw = Vector{typeof(u)}(undef, num_stages) if mass_matrix isa UniformScaling # `UniformScaling` doesn't play nicely with broadcast - for i in 1 : num_stages + for i in 1:num_stages z[i] = @.. mass_matrix.λ * w[i] #scaling by eigenvalue end else @@ -1468,18 +1475,20 @@ end #dw = Vector{typeof(u)}(undef, num_stages) z[1] = _reshape(LU1 \ _vec(rhs[1]), axes(u)) - for i in 2 :(num_stages + 1) ÷ 2 - tmp = _reshape(LU2[i - 1] \ _vec(@.. rhs[2 * i - 2] + rhs[2 * i - 1] * im), axes(u)) + for i in 2:((num_stages + 1) ÷ 2) + tmp = _reshape( + LU2[i - 1] \ _vec(@.. rhs[2 * i - 2] + rhs[2 * i - 1] * im), axes(u)) z[2 * i - 2] = @.. real(tmp) z[2 * i - 1] = @.. imag(tmp) end - integrator.stats.nsolve +=(num_stages + 1) ÷ 2 + integrator.stats.nsolve += (num_stages + 1) ÷ 2 # compute norm of residuals iter > 1 && (ndwprev = ndw) ndw = 0.0 - for i in 1 : num_stages - ndw += internalnorm(calculate_residuals(z[i], uprev, u, atol, rtol, internalnorm, t), t) + for i in 1:num_stages + ndw += internalnorm( + calculate_residuals(z[i], uprev, u, atol, rtol, internalnorm, t), t) end # check divergence (not in initial step) @@ -1493,17 +1502,17 @@ end break end end - - for i in 1 : num_stages + + for i in 1:num_stages w[i] = @.. w[i] - z[i] end # transform `w` to `z` #z = T * w - for i in 1:num_stages - 1 + for i in 1:(num_stages - 1) z[i] = @.. zero(u) for j in 1:num_stages - z[i] = @.. z[i] + T[i,j] * w[j] + z[i] = @.. z[i] + T[i, j] * w[j] end end z[num_stages] = @.. T[num_stages, 1] * w[1] @@ -1513,13 +1522,12 @@ end i += 2 end - # 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 + Convergence fail_convergence = false break end @@ -1534,15 +1542,15 @@ end cache.iter = iter u = @.. uprev + z[num_stages] - + if adaptive tmp = 0 - for i in 1 : num_stages - tmp = @.. tmp + e[i]/dt * z[i] + for i in 1:num_stages + tmp = @.. tmp + e[i] / dt * z[i] end mass_matrix != I && (tmp = mass_matrix * tmp) #utilde = @.. broadcast=false 1 / γ * dt * integrator.fsalfirst + tmp - utilde = @.. broadcast=false integrator.fsalfirst + tmp + utilde = @.. broadcast=false integrator.fsalfirst+tmp if alg.smooth_est utilde = _reshape(LU1 \ _vec(utilde), axes(u)) integrator.stats.nsolve += 1 @@ -1551,7 +1559,7 @@ end integrator.EEst = internalnorm(atmp, t) if !(integrator.EEst < oneunit(integrator.EEst)) && integrator.iter == 1 || - integrator.u_modified + integrator.u_modified f0 = f(uprev .+ utilde, p, t) OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) #utilde = @.. broadcast=false 1 / γ * dt * f0 + tmp @@ -1569,17 +1577,19 @@ end cache.dtprev = dt if alg.extrapolant != :constant derivatives = Matrix{typeof(u)}(undef, num_stages, num_stages) - derivatives[1, 1] = @.. z[1] / c[1] - for j in 2 : num_stages + derivatives[1, 1] = @.. z[1] / c[1] + for j in 2:num_stages derivatives[1, j] = @.. (z[j - 1] - z[j]) / (c[j - 1] - c[j]) #first derivatives end - for i in 2 : num_stages - derivatives[i, i] = @.. (derivatives[i - 1, i] - derivatives[i - 1, i - 1]) / c[i] - for j in i+1 : num_stages - derivatives[i, j] = @.. (derivatives[i - 1, j - 1] - derivatives[i - 1, j]) / (c[j - i] - c[j]) #all others + for i in 2:num_stages + derivatives[i, i] = @.. (derivatives[i - 1, i] - + derivatives[i - 1, i - 1]) / c[i] + for j in (i + 1):num_stages + derivatives[i, j] = @.. (derivatives[i - 1, j - 1] - + derivatives[i - 1, j]) / (c[j - i] - c[j]) #all others end end - for i in 1 : num_stages + for i in 1:num_stages cache.cont[i] = @.. derivatives[i, num_stages] end end @@ -1595,10 +1605,10 @@ end @muladd function perform_step!(integrator, cache::AdaptiveRadauCache, repeat_step = false) @unpack t, dt, uprev, u, f, p, fsallast, fsalfirst = integrator - @unpack num_stages, tabs = cache - tab = tabs[(num_stages - 1) ÷ 2] + @unpack num_stages, tabs, index = cache + tab = tabs[index] @unpack T, TI, γ, α, β, c, e = tab - @unpack κ, cont, derivatives, z, w, c_prime, αdt, βdt= cache + @unpack κ, cont, derivatives, z, w, c_prime, αdt, βdt = cache @unpack dw1, ubuff, dw2, cubuff, dw = cache @unpack ks, k, fw, J, W1, W2 = cache @unpack tmp, atmp, jac_config, linsolve1, linsolve2, rtol, atol, step_limiter! = cache @@ -1609,9 +1619,9 @@ end # precalculations γdt = γ / dt - for i in 1 : (num_stages - 1) ÷ 2 - αdt[i] = α[i]/dt - βdt[i] = β[i]/dt + for i in 1:((num_stages - 1) ÷ 2) + αdt[i] = α[i] / dt + βdt[i] = β[i] / dt end (new_jac = do_newJ(integrator, alg, cache, repeat_step)) && @@ -1619,8 +1629,24 @@ end 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] - for i in 1 : (num_stages - 1) ÷ 2 - W2[i][II] = -(αdt[i] + βdt[i] * im) * mass_matrix[Tuple(II)...] + J[II] + end + if !isthreaded(alg.threading) + @inbounds for II in CartesianIndices(J) + for i in 1:((num_stages - 1) ÷ 2) + W2[i][II] = -(αdt[i] + βdt[i] * im) * mass_matrix[Tuple(II)...] + J[II] + end + end + else + let W1 = W1, W2 = W2, γdt = γdt, αdt = αdt, βdt = βdt, + mass_matrix = mass_matrix, + num_stages = num_stages, J = J + + @inbounds @threaded alg.threading for i in 1:((num_stages - 1) ÷ 2) + for II in CartesianIndices(J) + W2[i][II] = -(αdt[i] + βdt[i] * im) * mass_matrix[Tuple(II)...] + + J[II] + end + end end end integrator.stats.nw += 1 @@ -1629,21 +1655,21 @@ end # TODO better initial guess if integrator.iter == 1 || integrator.u_modified || alg.extrapolant == :constant cache.dtprev = one(cache.dtprev) - for i in 1 : num_stages + for i in 1:num_stages @.. z[i] = map(zero, u) @.. w[i] = map(zero, u) @.. cache.cont[i] = map(zero, u) end else c_prime[num_stages] = dt / cache.dtprev - for i in 1 : num_stages - 1 + for i in 1:(num_stages - 1) c_prime[i] = c[i] * c_prime[num_stages] end - for i in 1 : num_stages # collocation polynomial + for i in 1:num_stages # collocation polynomial @.. z[i] = cont[num_stages] * (c_prime[i] - c[1] + 1) + cont[num_stages - 1] j = num_stages - 2 while j > 0 - @.. z[i] *= (c_prime[i] - c[num_stages - j] + 1) + @.. z[i] *= (c_prime[i] - c[num_stages - j] + 1) @.. z[i] += cont[j] j = j - 1 end @@ -1653,7 +1679,7 @@ end for i in 1:num_stages @.. w[i] = zero(u) for j in 1:num_stages - @.. w[i] += TI[i,j] * z[j] + @.. w[i] += TI[i, j] * z[j] end end end @@ -1669,7 +1695,7 @@ end # evaluate function ks[1] = fsallast - for i in 1 : num_stages + for i in 1:num_stages @.. tmp = uprev + z[i] f(ks[i], tmp, p, t + c[i] * dt) end @@ -1679,19 +1705,19 @@ end for i in 1:num_stages @.. fw[i] = zero(u) for j in 1:num_stages - @.. fw[i] += TI[i,j] * ks[j] + @.. fw[i] += TI[i, j] * ks[j] end end if mass_matrix === I Mw = w elseif mass_matrix isa UniformScaling - for i in 1 : num_stages - mul!(z[i], mass_matrix.λ, w[i]) + for i in 1:num_stages + mul!(z[i], mass_matrix.λ, w[i]) end Mw = z else - for i in 1 : num_stages + for i in 1:num_stages mul!(z[i], mass_matrix, w[i]) end Mw = z @@ -1701,24 +1727,52 @@ end needfactor = iter == 1 && new_W if needfactor - cache.linsolve1 = dolinsolve(integrator, linsolve1; A = W1, b = _vec(ubuff), linu = _vec(dw1)).cache + cache.linsolve1 = dolinsolve( + integrator, linsolve1; A = W1, b = _vec(ubuff), linu = _vec(dw1)).cache else - cache.linsolve1 = dolinsolve(integrator, linsolve1; A = nothing, b = _vec(ubuff), linu = _vec(dw1)).cache - end - - for i in 1 :(num_stages - 1) ÷ 2 - @.. cubuff[i]=complex( - fw[2 * i] - αdt[i] * Mw[2 * i] + βdt[i] * Mw[2 * i + 1], fw[2 * i + 1] - βdt[i] * Mw[2 * i] - αdt[i] * Mw[2 * i + 1]) - if needfactor - cache.linsolve2[i] = dolinsolve(integrator, linsolve2[i]; A = W2[i], b = _vec(cubuff[i]), linu = _vec(dw2[i])).cache - else - cache.linsolve2[i] = dolinsolve(integrator, linsolve2[i]; A = nothing, b = _vec(cubuff[i]), linu = _vec(dw2[i])).cache + cache.linsolve1 = dolinsolve( + integrator, linsolve1; A = nothing, b = _vec(ubuff), linu = _vec(dw1)).cache + end + + if !isthreaded(alg.threading) + for i in 1:((num_stages - 1) ÷ 2) + @.. cubuff[i] = complex( + fw[2 * i] - αdt[i] * Mw[2 * i] + βdt[i] * Mw[2 * i + 1], + fw[2 * i + 1] - βdt[i] * Mw[2 * i] - αdt[i] * Mw[2 * i + 1]) + if needfactor + cache.linsolve2[i] = dolinsolve(integrator, linsolve2[i]; A = W2[i], + b = _vec(cubuff[i]), linu = _vec(dw2[i])).cache + else + cache.linsolve2[i] = dolinsolve(integrator, linsolve2[i]; A = nothing, + b = _vec(cubuff[i]), linu = _vec(dw2[i])).cache + end + end + else + let integrator = integrator, linsolve2 = linsolve2, fw = fw, αdt = αdt, + βdt = βdt, Mw = Mw, W1 = W1, W2 = W2, + cubuff = cubuff, dw2 = dw2, needfactor = needfactor + + @threaded alg.threading for i in 1:((num_stages - 1) ÷ 2) + #@show i == Threads.threadid() + @.. cubuff[i] = complex( + fw[2 * i] - αdt[i] * Mw[2 * i] + βdt[i] * Mw[2 * i + 1], + fw[2 * i + 1] - βdt[i] * Mw[2 * i] - αdt[i] * Mw[2 * i + 1]) + if needfactor + cache.linsolve2[i] = dolinsolve( + integrator, linsolve2[i]; A = W2[i], + b = _vec(cubuff[i]), linu = _vec(dw2[i])).cache + else + cache.linsolve2[i] = dolinsolve( + integrator, linsolve2[i]; A = nothing, + b = _vec(cubuff[i]), linu = _vec(dw2[i])).cache + end + end end end integrator.stats.nsolve += (num_stages + 1) / 2 - for i in 1 : (num_stages - 1) ÷ 2 + for i in 1:((num_stages - 1) ÷ 2) @.. dw[2 * i - 1] = real(dw2[i]) @.. dw[2 * i] = imag(dw2[i]) end @@ -1727,7 +1781,7 @@ end iter > 1 && (ndwprev = ndw) calculate_residuals!(atmp, dw1, uprev, u, atol, rtol, internalnorm, t) ndw = internalnorm(atmp, t) - for i in 2 : num_stages + for i in 2:num_stages calculate_residuals!(atmp, dw[i - 1], uprev, u, atol, rtol, internalnorm, t) ndw += internalnorm(atmp, t) end @@ -1744,17 +1798,17 @@ end end end - @.. w[1] = w[1] - dw1 - for i in 2 : num_stages + @.. w[1] = w[1] - dw1 + for i in 2:num_stages @.. w[i] = w[i] - dw[i - 1] end # transform `w` to `z` #mul!(z, T, w) - for i in 1:num_stages - 1 + for i in 1:(num_stages - 1) @.. z[i] = zero(u) for j in 1:num_stages - @.. z[i] += T[i,j] * w[j] + @.. z[i] += T[i, j] * w[j] end end @.. z[num_stages] = T[num_stages, 1] * w[1] @@ -1786,12 +1840,12 @@ end @.. broadcast=false u=uprev + z[num_stages] step_limiter!(u, integrator, p, t + dt) - + if adaptive utilde = w[2] @.. tmp = 0 - for i in 1 : num_stages - @.. tmp += e[i]/dt * z[i] + for i in 1:num_stages + @.. tmp += e[i] / dt * z[i] end mass_matrix != I && (mul!(w[1], mass_matrix, tmp); copyto!(tmp, w[1])) #@.. ubuff=1 / γ * dt * integrator.fsalfirst + tmp @@ -1799,7 +1853,7 @@ end if alg.smooth_est cache.linsolve1 = dolinsolve(integrator, linsolve1; b = _vec(ubuff), - linu = _vec(utilde)).cache + linu = _vec(utilde)).cache integrator.stats.nsolve += 1 end @@ -1818,7 +1872,7 @@ end if alg.smooth_est cache.linsolve1 = dolinsolve(integrator, linsolve1; b = _vec(ubuff), - linu = _vec(utilde)).cache + linu = _vec(utilde)).cache integrator.stats.nsolve += 1 end @@ -1831,16 +1885,18 @@ end cache.dtprev = dt if alg.extrapolant != :constant @.. derivatives[1, 1] = z[1] / c[1] - for j in 2 : num_stages + for j in 2:num_stages @.. derivatives[1, j] = (z[j - 1] - z[j]) / (c[j - 1] - c[j]) #first derivatives end - for i in 2 : num_stages - @.. derivatives[i, i] = (derivatives[i - 1, i] - derivatives[i - 1, i - 1]) / c[i] - for j in i+1 : num_stages - @.. derivatives[i, j] = (derivatives[i - 1, j - 1] - derivatives[i - 1, j]) / (c[j - i] - c[j]) #all others + for i in 2:num_stages + @.. derivatives[i, i] = (derivatives[i - 1, i] - + derivatives[i - 1, i - 1]) / c[i] + for j in (i + 1):num_stages + @.. derivatives[i, j] = (derivatives[i - 1, j - 1] - + derivatives[i - 1, j]) / (c[j - i] - c[j]) #all others end end - for i in 1 : num_stages + for i in 1:num_stages @.. cache.cont[i] = derivatives[i, num_stages] end end diff --git a/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl b/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl index 7191eabdb2..f2b92910a9 100644 --- a/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl +++ b/lib/OrdinaryDiffEqFIRK/src/firk_tableaus.jl @@ -269,279 +269,46 @@ struct RadauIIATableau{T1, T2} e::Vector{T1} end -function RadauIIATableau5(T1, T2) - γ = convert(T1, big"3.63783425274449573220841851357777579794593608687391153215117488565841871456727143375130115708511223004183651123208497057248238260532214672028700625775335843") - α = T1[big"2.68108287362775213389579074321111210102703195656304423392441255717079064271636428312434942145744388497908174438395751471375880869733892663985649687112332242"] - β = T2[big"3.05043019924741056942637762478756790444070419917947659226291744751211727051786694870515117615266028855554735929171362769761399150862332538376382934625577549"] - - c = T2[big"0.155051025721682190180271592529410860803405251934332987156730743274903962254268497346014056689535976518140539877338581087514113454016224265837421604876272084", - big"0.644948974278317809819728407470589139196594748065667012843269256725096037745731502653985943310464023481859460122661418912485886545983775734162578395123729143", - 1] - - e = T1[big"-10.0488093998274155624603295076470799145872107881988969663429493235855742140670683952596720105774938812433874028620997746246706860729547671304601625528869782", - big"1.38214273316074889579366284098041324792054412153223029967628265691890754740040172859300534391082721457672073619543310795800401940628810046379349588622031217", - -1//3] - - TI = Matrix{T1}(undef, 3, 3) - TI[1, 1] = big"4.32557989006315535102435095295614882731995158490590784287320458848019483341979047442263696495019938973156007686663488090615420049217658854859024016717169837" - TI[1, 2] = big"0.339199251815809869542824974053410987511771566126056902312311333553438988409693737874718833892037643701271502187763370262948704203562215007824701228014200056" - TI[1, 3] = big"0.541770539935874871186523033492089631898841317849243944095021379289933921771713116368931784890546144473788347538203807242114936998948954098533375649163016612" - TI[2, 1] = big"-4.17871859155190472734646265851205623000038388214686525896709481539843195209360778128456932548583273459040707932166364293012713818843609182148794380267482041" - TI[2, 2] = big"-0.327682820761062387082533272429616234245791838308340887801415258608836530255609335712523838667242449344879454518796849992049787172023800373390124427898159896" - TI[2, 3] = big"0.476623554500550451960069084091012497939942928625055897109833707684876604712862299049343675491204859381277636585708398915065951363736337328178192801074535132" - TI[3, 1] = big"-0.502872634945786875951247343139544292859248429570937886791036339034110181540695221500843782634464164585836226038438397328726973424362168221527501738985822875" - TI[3, 2] = big"2.57192694985560542918678535360167505469448742842178326395573566888176471664393761903447163100353067504020263109067033226021288356347565113471227052083596358" - TI[3, 3] = big"-0.596039204828224924968821911099302403289857517521591823052174732952989090998130905722763344484798508456930766594977798579939415052669401095404149917833710127" - - T = Matrix{T1}(undef, 3, 3) - T[1, 1] = big"0.091232394870892942791548135249436196118684699372210280712184363514099824021240149574725365814781580305065489937969163922775110463056339192206701819661425186" - T[1, 2] = big"-0.141255295020954208427990383807797309409263248498594798844289981408804297900674604638610419147468875667691398225003133444988034605081071965848437945842767211" - T[1 ,3] = big"-0.0300291941051474244918611170890538666683842974606300802563717702200388818691214144173874588956764952224874407424115249418136547481236684478531215095064078994" - T[2, 1] = big"0.241717932707107018957474779310148232884879540532595279746187345714229132659465207414913313803429072060469564350914390845001169448350326344874859416624577348" - T[2, 2] = big"0.204129352293799931995990810298338174086540402523315938937516234649384944528706774788799548853122282827246947911905379230680096946800308693162079538975632443" - T[2, 3] = big"0.382942112757261937795438233599873210357792575012007744255205163027042915338009760005422153613194350161760232119048691964499888989151661861236831969497483828" - T[3, 1] = big"0.966048182615092936190567080794590794996748754810883844283183333914131408744555961195911605614405476210484499875001737558078500322423463946527349731087504518" - T[3, 2] = 1 - T[3, 3] = 0 - RadauIIATableau{T1, T2}(T, TI, - c, γ, α, β, e) -end - -function RadauIIATableau9(T1, T2) - γ = convert(T1, big"6.28670475172927664517315334186940904959068186655567041187229167532923622489525703260842273089261139845280626287956099768662193453067483410165932355981736786") - - α = T1[big"3.65569432546357225824320796009543385435699888857815445045567025741630720509235614026228963385258117304229337679733945535812317372403535763551850772878775217", - big"5.70095329867178941917021536896986162084766017814401034360818390491907468246001534343349900070111312773130349176288004579856585901062722531365183049130382405"] - β = T1[big"6.5437368993600772940210715093936863183637851728134458820202187133882261290012752452972782843700946890488789462524897903624959996932392239962196563965573345", - big"3.21026560030854988842501065297211721232153653493981008029923647488964744732168461657389754087826565709085773529539707072244537983491480773006949966789260925"] - - c = T2[big"0.0571041961145176821931211925541156212350779455987501643278082929309346782020731645861138168198427368635148018903413155731609901559772929443100370500757072557", - big"0.276843013638123827680045997685625141110889169695030468349442048831121339683708036772541528564051130879197377136636984534220758899839905855114024309075271826", - big"0.583590432368916820056697668662917248693432639896771640176293841831747501961831012005632277467456299345321045569611992496682381919275766424103024358378365496", - big"0.8602401356562194478479129188751197667383780225872255049242335941839742579301655644134901549264276106897445531811874851737136468026848125542506920602484255", - 1.0] - - e = T1[big"-27.7809339440646373047872078172168798923674228687740760060378492475924178050505976287227228556471699142365371740120443650701118024100678675823465762727483305", - big"3.64147849804921315271165508774289722904088750334220956841022786858917594981395319605788667956024462601802006251583142928630101075351336314632135787805261686", - big"-1.25254772116911872049065249430114914889315244289570569309128740586057170336299694248256681515155624683225624015343224399700466177251702555220815764199263189", - big"0.592003167184542872566205223775131812219687808327572130718908784863813558599641375147402991238481535050773351649645179780815453429071529988233376036688329872", - -1//5] - - TI = Matrix{T1}(undef, 5, 5) - TI[1, 1] = big"30.0415677215444016277146611632467970747634862837368422955138470463852339244593400023985957753164599415374157317627305099177616927640413043608408838747985125" - TI[1, 2] = big"13.8651078562714131651762946846279728486098595017962436746405940971751244384714668104145151259298432908422191238542910724677205181071665482818120092330632702" - TI[1 ,3] = big"3.48000277479518556182840016971955819123081637245954095062693470191383865922357339844125383481645392882289968250993872221445874555610460465838129969397069557" - TI[1, 4] = big"-1.03200879782526342277108071214631493513824682491749273908106331923801396656058254294323988505859654767877050109789490714699847664805679842903430004696170252" - TI[1, 5] = big"0.804303045073989917475330383606196086089578671788707543063308602519859970319818304759856653218877415405946945572102875643297890954688508528143272905631829894" - TI[2, 1] = big"5.34418643783491159889531030409736033885455686563071401172022718575590068536629704134603404624953791012861634674294690788961703408019660066685859393456498931" - TI[2, 2] = big"4.59361556775916100445407449817656238428260055301676371438973411021009514435572975394999086474831271997070798032181411537895658457000537727156665947774751386" - TI[2, 3] = big"-3.03636032345942429864615756872018980250277648141683630832856906288036929718223473102394179699607901856890769270810252103326382063852039607285826867723587514" - TI[2, 4] = big"1.05066019023145886385983615715299311307615150447133905233370933194949591737765763708886464382722316727972166443876395823044171403663404254906698768838255919" - TI[2, 5] = big"-0.272778611864296270538614649997366804891835224042737605275699398413256470423268908248569612750117948720141667949532252500428432062582365619208502333677907158" - TI[3, 1] = big"3.74805980743980486005103450189256983678052751095791526209741655305580351377124372457009580386663275146166007984852101733055495783906881063060757645038080343" - TI[3, 2] = big"-3.98496573634388466725226385805351110838575115293851360514636734529255361185420464416807882769853298186283398369873418552760618971047757002216338511286260041" - TI[3, 3] = big"-1.04441564160801879294224732309562532189841624726401645191058551173485917137499204844819781779667611903670073971659834929382224472890100209497741235960707456" - TI[3, 4] = big"1.18409856813794848723102038838340482030291345603197522521517834943166421242518751666675199211369552058487095283489346390066317584532997854692445653563909898" - TI[3, 5] = big"-0.449917770156780368898811918314095435942113881883174152777026977062686286863549565130412864190301081537983106397709991028107600781961279985605930655683680139" - TI[4, 1] = big"-33.0418802135190000080614469426109507742858088371383868670878639187564531424382858814386742148456699143328462132296293097447566408853495288807407929988004676" - TI[4, 2] = big"-17.3769534790635670194549806058987105852733409102703844354448800193942184746909147697382687117638715195698950138089979798321855885541817752366521518811413713" - TI[4, 3] = big"-0.172129063254005561151528806427751383749451500597823574207174433146207178559871803504021077429693091164540897873472803934375603405253541639437370184767553293" - TI[4, 4] = big"-0.0991697779825426425881662214017368584726354746776989845479783944003623924121748016326495070834800297497011104846871751430208559227945252758721362340763610828" - TI[4, 5] = big"0.531228115838306667184911422606024795426589562580669892779793097035561488973256023529352389498509937781553683467106048413485632583844632286562240161995145055" - TI[5, 1] = big"-8.61144397987529197770008251257034851950485933115010902789613925540488896812417081206983938638600226846804467531843522104806738090683710882069500386691775154" - TI[5, 2] = big"9.69999140952880823133589405342003266497120753048627084327055311528684684237122654108691149692242002085965723391934376924400492239317026460192827344970015484" - TI[5, 3] = big"1.91472863969687428485137560339172471528025297511003983469957355306260543484472462223194401768126877615795915146192537091374017807611943419264038682143890747" - TI[5, 4] = big"2.41869200608494002642656343408298350771199306961305597858229870375990977712805399625496435641846363295393762353024017195444763964531237381728801981679934304" - TI[5, 5] = big"-1.0474634879353374186944329992117360176590042540536055452919974336199826846201614544718272622833822842591012529895091659029452542118642301415759073410771819" - - T = Matrix{T1}(undef, 5, 5) - T[1, 1] = big"0.0125175862205010458901356760368001462557655123420858705973577952199246108029451084239310924615007306721702298573083400752464277227557045438770401832498107968" - T[1, 2] = big"-0.0102420478179088270700863300668590125015813934827825923708366359399562125950804289592272678367034071306578383319296130180550178248531589487456925441921649293" - T[1 ,3] = big"0.0476738772902957238631839478592069782970238490568258436986723993118380988311441474394156362952631834786373081794857384127209450988829840886524135970873769918" - T[1, 4] = big"-0.0114785152552295147079415554121555049385506204591245712490409384029671974157542450636658532835395855844059342442518520033304129991000509527123870917346017759" - T[1, 5] = big"-0.0140198588928754102810778942934959307831026572823203692568448424056201483917805257790275956734469193171917730378117501915144713896813544630288006687542182225" - T[2, 1] = big"0.00149167015189538242900444775236282223594625052328927847572623038484966999313257893341818287477809424303168766872838075463220122499449382436194198620498144296" - T[2, 2] = big"0.050172864517371058162991380262646513853120568882725793734131676894272706020317186004736779675826101816279321643304301437029912742375638648226701787880031719" - T[2, 3] = big"-0.0943318191816114369806569003363724471884924328367212069321438749304281980331334016578193750445513659941246363262225907407726099492713722343006925656625258579" - T[2, 4] = big"-0.00766883074918016288515687679203608074116106558796378201472238095295554979920808799930579174190884587422912077296093093698836937450535804218413704866981728518" - T[2, 5] = big"0.024708578426518526812525205377780382655366504554979744093019395818934704623702078004474076773426928900579988063099593288435684744957695210778788200213260272" - T[3, 1] = big"0.072981876388087148622657299703669587832652508881663282287850495621401398441897288250625556038835308015912409648841893161563884759791665776933761278383553608" - T[3, 2] = big"-0.230539534043417946721421862180000422679228296568599014834226319726930529322581417981617275287468418138394077987361681288909676234537699721082090802790143303" - T[3, 3] = big"0.102703045380125899792210456947141185148813233939327773583525878521508211077874610560448598369259541346968946573971195783374996178436435357335759255990489434" - T[3, 4] = big"0.0193984639988289509112232896408330872285824216708905773930244363652651247181543158008567311548336143384128605013911312875018664026371225431993252265128272262" - T[3, 5] = big"0.0818003537037511708363908122287572533071340646031113975848869261019231448226334426630664318901554550460201409321555775999869184033436795623062614812355590017" - T[4, 1] = big"0.380091440003568104126439184355215575526619121262253024859378518379910007234696730891540745160675744992320824590679292148769326540463161583672773762554445506" - T[4, 2] = big"0.377893902248861249543862293745933995234687511602719536459666284734445918178134851270924212812363352965391508894581698067329905034837778770261095647458874628" - T[4, 3] = big"0.466744130332494359289559582964906703283968612669234331018678042733321473730897217606173184300477207393539851157929838664168404778962779344509707214938022808" - T[4, 4] = big"0.40760117128019906662166237021895987274626181127101561893104166874567447589187790736078997321464949349935802836110699884016973990503134772720646054039223561" - T[4, 5] = big"0.199682427886802525936540566022390695167018315867216115995143539347975271751460199398235415129329119718414206048034051939441434136353381864781262773401023899" - T[5, 1] = big"0.921978973681210488488254647415676321266345412943047462855852351388222898143904205962703147998267738964059170225806964893009202287585991334322032058414768529" - T[5, 2] = 1 - T[5, 3] = 0 - T[5, 4] = 1 - T[5, 5] = 0 +import LinearAlgebra: eigen +import FastGaussQuadrature: gaussradau - RadauIIATableau{T1, T2}(T, TI, - c, γ, α, β, e) +function RadauIIATableau{T1, T2}(tab::RadauIIATableau{T1, T2}) where {T1, T2} + RadauIIATableau{T1, T2}(tab.T, tab.TI, tab.c, tab.γ, tab.α, tab.β, tab.e) end -function RadauIIATableau13(T1, T2) - γ = convert(T1, big"8.93683278840521633730209691330107970355008194433956657198414191417624969654351559268800871286734194720118970058657997472527299153742511021973612156231867783") - α = T1[big"4.37869356150680600252334919268856129165763746518197948235657247177701087073069907016715245914093899486193202405685779803686971216417800783050995450529391908", - big"7.14105521918764010577498142571556804318193862372238812855726792587872300446315860222917039505087745633962330233504078264632719519730762016919715839787116038", - big"8.51183482510294572305062092494533081338538293892584910309408864525614127653438453125967278937451257519784982331481143195416659686980181689042482631568989031"] - β = T1[big"10.1696932837950116273183544188477298930096536824510223588525334625762336174947183926243705927725260475934351162622185429326813205432867247703480391692806137", - big"6.62304592263927597062055811591186110468148199066707542227575094761515104946479159063603447729283770429494038962408904312215452856333028405675512985803584472", - big"3.2810136243250588300359425270393915846791621918405321383787427650552081712406957205287551182809705166989352673500472974040971593568323836675590314648604458"] - - c = T2[big"0.0293164271597848919720502769131649103737303925637149277869106839449360382416657787486309483651843695097273923248526200112627747993405898353736305552306269904", - big"0.148078599668484291849976852495979212230248774808594461412594641801598386090878321806369397661747576057906341132861865305306667654594593138746653233717241913", - big"0.336984690281154299097052972080775705197568750028473347122562968073691350512784060852409141173654482529393236826516171319486086447256539582972346127980810124", - big"0.558671518771550132081393341805521940074368288965407825555747226117350122897421078323820052012282581935200398463518265914564420109615277886000739200777932339", - big"0.769233862030054500916883360115645451837142143322295416166948169636548130573953285685200211542774367652885154701431860087378103033801830280742146083476036669", - big"0.926945671319741114851873965819682011056172419542283252724467079656645202452528243814339480013587391545656707320049986592771178724621938506933715568048004783", - 1] - - e = T1[big"-54.374436894128614514583710369683221528326818668136315170227649609831132483812209590903458627819914413600703287942266678601263304348350182019714004102122958", - big"7.00002400425918651204068363735192307633403862621907697222411411256593188888314837387690262103761082115674234000933589934965063951414231971808906314491204573", - big"-2.35566109198755719225604586775720723211163199654640573606711168106849118084357027539414093812951288166804790294091903523762277368547775099880612390898224076", - big"1.13228906610613438638449290827978318662460499026070073842612187085281352278780837966549916347601259689966925986653914736463076068138934273474363230390185871", - big"-0.646891326767358711867345222439989069591870662562921671446738173180691199552327090727940249497816198076028398716990245669520129053944261569921119452534594627", - big"0.387533385375352377424782057105854424214534853623007724234120623518712309680007346340280888076477218145510846867158055651267664035097674992751409157682864641", - -1//7] - - TI = Matrix{T1}(undef, 7, 7) - TI[1, 1] = big"258.131926319982229276108947425184471333411128774462923076434633414645220927977539758484670571338176678808837829326061674950321562391576244286310404028770676" - TI[1, 2] = big"189.073763081398508951976143411165126555759459745371576264125287430947886413126866952443113984840310549596923934762141954737541643761162558070450614795561734" - TI[1, 3] = big"49.0873148179301311944474703372633419330229683717897887664283914712555334645741343066714059043135343948204451450061803442374878045458955826422757210762412997" - TI[1, 4] = big"4.11064746966142841811238518636124668078589358089581133578005291508858571621836624121708112101643343488669794287298806656198949715476379639435093560435010553" - TI[1, 5] = big"4.05344788931556330417512803837862541661144275947069236866476426664242632965376171604053865483440478823853326237912519148507906655855071507442222711969825069" - TI[1, 6] = big"-3.11275536660734607655357698925636361735741304308245452106573904595716690770542970584435712650159533448326091358879097717388530116398450168049097806992817596" - TI[1, 7] = big"1.64677491355844465016894934800942442334612077828885771793164268655566366462165061862443368822544695623147966149765223644798045399342853834086413561960176148" - TI[2, 1] = big"-3.00739016945129213173149353792169083141834116044470099212013728771587881480191343754504173052952073006187734389002396348355357273701343509199048972794392147" - TI[2, 2] = big"-11.0158660787657713291120393664792067595453921824881213620299497076376976067619617086470844707815815293102862568459526162951253770377715406520772358338647188" - TI[2, 3] = big"1.48779945613165628148618248664965038886474377325027865838645297753993182317594482435706956176392903188004580583104018591540474622009639200188521283880201225" - TI[2, 4] = big"2.13038815955928245943197208332824475219642634294808813866153957342980992047877237670079423767538654092424134276380826377135080667266661637001176204430488753" - TI[2, 5] = big"-1.81614108681756562482220455159496741723359999245934818387747079566312917815672128128449281415737713177900591942282975861961228230314168417307836619006791605" - TI[2, 6] = big"1.13432558789516110008277908420532415765361628740656810686297793967986689714948610119162966211301325316623863222505219543867472186257492829970663316956377323" - TI[2, 7] = big"-0.414699045943303531993049422295928526684402022493736427543557958358387925728160703636844863663828153394608981043415378230601486738224597324364079320598162815" - TI[3, 1] = big"-8.44196318832108468175691559413731210343158392484322786670758421404507417209484447031645790366021837365786640573614305718894911853549168061902141351516580451" - TI[3, 2] = big"-0.650525274057515002816904045893485631294530894981669254094573985727348985809697093879080285963063573837365484483755274668080611163704039179328960851461387071" - TI[3, 3] = big"6.94067073036987647880408175445008301222030789462375109942012235845495260572570799226646472429196555932436186979400567616504159564738984233922289782922787445" - TI[3, 4] = big"-3.20504752559789843156502799159713971965747774043426947358779973217345866996463287674334224123932879873323284636947452187683408110992957222808611161423213549" - TI[3, 5] = big"1.07128094354647858978279562700457911254627057919002861801894953308482120936700881726232902304000322718645130593907512149815870969208873216470962770569998532" - TI[3, 6] = big"-0.354850749121622187972972761073874956531274189535504546398851680169235702590362534883357256681588685608802983372517893712333972644320006895019178184808028042" - TI[3, 7] = big"0.0919854913278655415440864884207305663999562250023079120516746551750254082665966708567906888946992351083964961208132558221142585217674963218388224937302473142" - TI[4, 1] = big"74.6783322350226997715286176267232500441551583987525066913719852490109364599462546293112601362342028584101507709386240000804692470037564789980905370400509214" - TI[4, 2] = big"87.4085889799008164020396362924136436577534600993283836959398121813667403209890699914314446222016952621954817633686823685774595935180374571416781238038364186" - TI[4, 3] = big"4.02415873737999787701407840793921059156554118449220356776918749072220128918152906578385457943212213189933447495921754693186811343717296680238755923076427455" - TI[4, 4] = big"-3.7148063151583641866387382381081795406061842159003055897302686185198568522128509989890869602984467843559169959313018612449354703104270603001605170037725663" - TI[4, 5] = big"-3.43009398598231735074090769130593476067104938465255451803266927011738721835297930406017172365070584279715308905584391225176154776278518922912169890517961929" - TI[4, 6] = big"2.69660480976531237885262500230842013033719691844775548640355919138284680959979836353143310081338215041119022648809147361433752919265159399610746756470853959" - TI[4, 7] = big"-0.938692743607546193356785681771531136814109179879957291315724533839534255667763099330792864148293396694586387338161584706252944483821135344465739888811338788" - TI[5, 1] = big"58.3565288519065772423731088606544342599129168115273649928818622008651860145833895668543250775742899696760389837877193028417145182338484929599333810581515993" - TI[5, 2] = big"-10.0687739578001809632495544545749228539542767485211306078205622876595603032162891608453826862136355989387474454697691529766293644115682409173741730758425432" - TI[5, 3] = big"-30.3663888425666712081087189214021522992426235463582449811325590575576319489955157279473313224901192335775884848736150180108985558310423628914140477437063457" - TI[5, 4] = big"-1.02002086518486598502718784312141857841892430616701325398305811243769008274372077411348691412296276168896198187688441456921700292037247387330560786140723416" - TI[5, 5] = big"-0.112417500378424962126670249921897816128157398591725875330925039631874967429838848482089690872916638698820411392685501889126627650123714184027159547685248056" - TI[5, 6] = big"1.89064083100037762279966919417932484200269828564004442737723486475878958135985745266991261770924069476112679285337233931312540904735632744873728510014970829" - TI[5, 7] = big"-0.971648639383148228217233127548943147296423534674266405843322723719694664032217172325052282800290275002731997713145411340983758516166807609661717915219518127" - TI[6, 1] = big"-299.18624802825209667863642523944728107942141534516550178278869311293354511449399684666660494133688445719285752471650937062695632169114367079856135650539072" - TI[6, 2] = big"-243.040745368744791181900565230083092669143049316165122405971394775932180012728275256467636352341415340547177922968547123544546515287229215470481168446631934" - TI[6, 3] = big"-48.7771040780378692121909344887388032694629956594617430615510915251995189158287187599892740037773277403958100797917560590738598108409472582147091119440886778" - TI[6, 4] = big"-2.03867190574193440528015205293433905622043272233073734690244789947707827347049413187234402189062846366658963666461334786306660732097114011309282331323116958" - TI[6, 5] = big"1.67356023986108494426829042309213202110891938292923077616474877079402040904687073610625868939896244842053999572446723558562427506280564629528151134946587118" - TI[6, 6] = big"-1.0873740320571061644555969255032311107358443063278089996181949045168433801494845898897631535619158410753032807069032950523487601457868753453652745002841107" - TI[6, 7] = big"0.901938249296099373842715514839004052963355800714627971724094542443991299921284427589690820402982448873149676210397055957126153220340909284180014056386791594" - TI[7, 1] = big"-93.076502897435305911571945263737383854569504715670989865831914555937966339933932282945955570244055882294556430466422133231853008314991630740535709028417842" - TI[7, 2] = big"23.8816310562811442770319002318043863376962876994405756649585750650966186536576789769674007990310112890015051984278059899811178135726914390958188405071290871" - TI[7, 3] = big"39.2788807308138438271015646136760366834412493325456249795727722130258444051594274416196392795817449902122139076648927894476044063388859377757097127385794539" - TI[7, 4] = big"14.3889156854910800698761307424979534708984169042483973564042387223013868069040933228077604321320066763752720714195604903398768371784013771964086553618150626" - TI[7, 5] = big"-3.51043839939936122108708432480845734972162782563284715495715984978907792386567906732993553255070093796782368160341757151292477304975079070782335737053297468" - TI[7, 6] = big"4.86328488556618070121491058699734313503568312572977577331134555924656926935558698308076704662503608259898740028814153544991114426972747448736702277116049277" - TI[7, 7] = big"-2.24648272959123991640046924839711232278867381637608763335081676684616443569602032178385937243819174902544136208243971053224668691848283004752869023074006745" - - T = Matrix{T1}(undef, 7, 7) - T[1, 1] = big"0.00215375462731052642282751906550204337272018200721827917615061640312650856312529840445028048591986867096756005142895325420603307041594804305862850861253757163" - T[1, 2] = big"0.021567551351320773386914226953811992365459277376204369162736830595700124529879508417849062386878143122032508776691627063229415272329484156789207145821702462" - T[1, 3] = big"0.00878356792514414440732555660043326940873333657406338685620618347939710728032290406426688328221296324998146697730909767495361893387567339044816921837538988154" - T[1, 4] = big"-0.00405516145233102389819844704090310382485225922827010954643577855973533421255114497764957587851178840064428149215351434824919490696577563849929483184955933965" - T[1, 5] = big"0.00442723275326828547967807873499027629097834766201549949492135358632150336069311115075327876323707841703727317338755331613570950287342825020738596326021052902" - T[1, 6] = big"-0.00123864618795287405637686870391105285581324510790128485733529975336279476721707053186563729417080236061385260749762448518679294700311105630290083016823761156" - T[1, 7] = big"-0.00276061748054385249954800379096675592021481213358861974911688001011761550911589157738523818859000828996335817774948428177282421412491830529445501318154035024" - T[2, 1] = big"-0.00160002507788042852683067347985080829550105638728462477214069614397009338180775134535418790113854904464693278677067195562013777079470430165035085043732753352" - T[2, 2] = big"-0.0381316481344115466944201512445271892551007922443248010648630183723114657457789198582213862424187595732944781586531399310738197517976083499508550510483478779" - T[2, 3] = big"-0.0215255605940068755238494349163503963236812065771639056145559371805737876208350036328339608215271680572576146954552666030277743869132676140541472724370558091" - T[2, 4] = big"0.00841556827655958923717700333156546206587781542530241328710392714333753219743181540077241302321588065650704924760060316717877095134935044662592211744890794666" - T[2, 5] = big"-0.00403194957022454949230429372587008587329606687054571010486662485715979240183165499902791387008699068626978608835015342675934092134962673636484308565473356683" - T[2, 6] = big"-6.6666353393963381817604789740257628821376819567901071737415235834331307484818353061850936507762955342131861918219584166678095273744210157164382779907235669e-05" - T[2, 7] = big"0.00318547482516620984874835878222687621122035448401205459368674257818574765593899794870819769668503869906022860261901897250913569265553156976061140932045107432" - T[3, 1] = big"0.00405910730194768309165024146216588597640781263680870767202041411242133338742562561902630276038676420444232405079851555753917806998064489819308813790494788924" - T[3, 2] = big"0.0573965089393817153975680203880753938458832782600090443030839643350468249623833638779578474891654213594195393636829414422184571666256857425091138479371917574" - T[3, 3] = big"0.0588505292084267910561208969865829735901655409220388105109199298038946675765714122525765330769443473927581930134049676200572930797370286476504623214740871248" - T[3, 4] = big"-0.00856043106160343206017727185390754992573940897343949944649743606465705403614377469754987858631901604547097801042861815249197647886051332362774581709381720893" - T[3, 5] = big"-0.00692321266502390892414068519049460069371592099748070119636478595631451405094203293036429762819458535062492059219566837532157551782305886338773933077463475632" - T[3, 6] = big"-0.00235218098294333834053519532555529491776729377182703234025085030409255592197086839142988525473684138901264206886166295186155491132922909402254443843846019141" - T[3, 7] = big"0.00041690777252975626914088803059940941342549922756308931704215701350026719541939053570614368159222367707113801117750298289694571643601584878405615892432648487" - T[4, 1] = big"0.0157504880793768442034586734054915501004520506405808322686493022779655453114657621318660532381583918124125360276320121127974912393389579826125529804830864399" - T[4, 2] = big"-0.0382146935969683504846411337659300127514788882892071252172987515109399372135899067290947441850340146027892665775682097051548343529370733593281856326317259999" - T[4, 3] = big"-0.165736811272943851241241116255535218556011122333381899790277357803281567727036568454939356458468926429537927937619042817050400333625919290585510785057955509" - T[4, 4] = big"-0.0373712423023844574190702119163246888117181457309185176497005310822879226235861373253125139016964433591381638592353617347369492240160809914228784174846477722" - T[4, 5] = big"0.00823900729850771940449868235563938395546999707236910359131464615707125576979409087864780171789078059526539789661318173387826643385244974406562622466790754233" - T[4, 6] = big"0.00311507115234617525272547086289315208054441921705361129575617631104650731644437585122142710666234276633544335552925569262424677362146587776195531866754755781" - T[4, 7] = big"0.025116604913438821928363823471446698278976101918753236732238210724710282378748917637317846485853317873304329580245705683618093593158791190832004186288367408" - T[5, 1] = big"0.112977661024220807608615842313106352633973778091080400075534257952348289641328709240673869677499013004285003126194992176632265223545565047727637631580337111" - T[5, 2] = big"-0.249174212465263686330825594009221950347570740813751325091913985975498424569678307894304962660904874986611526140914403971840496728150916599999921976188547708" - T[5, 3] = big"0.273563305798662321213236935135336593478278696397012151365678540099566245199777083242808233574654642014215983653810819494932091426330017240672955510133726276" - T[5, 4] = big"0.00536676137918177009427930181087914853701809128264121101773394730339300080525157052081366996826642003169044168721911822166683675089051631342776752635189343996" - T[5, 5] = big"0.193211116101262014431211225620266980060733605289133050251158448403922545905872373640500736693735926480983370235582910255756813799388364741420161359961401418" - T[5, 6] = big"0.101717732481715146808078931323995112561027763392448195424858681165964478003318758266672250034474900552688318026734856778296896546916272032434282368222825518" - T[5, 7] = big"0.0950450203560462282103892144485647895183175432965514336285840628832838918715022627077373617151475963061484489345238022187829573892306346658797861719620799413" - T[6, 1] = big"0.458381043183931501028085939964292092908293295595258886425372669820276128937720150467378912424378376379185138190017965370589550781979145790869568608776861466" - T[6, 2] = big"0.5315846490836284292050500994300107341125728347976407285397462896004659632807779347307732180848765709277026749725126234633983063167374333425454720010026876" - T[6, 3] = big"0.486322836617572894056685295353340203321316764127126557475136642083389075853199222650975554544550110757249234979120491845825690852575400863926535437662617201" - T[6, 4] = big"0.526574226458449262914091192639271913456008564881594253716678163127743947224108435833618497118891017505982561930788522171455486058320589875335702474378251931" - T[6, 5] = big"0.275534394989625814192875938762525038291639319966986287664787801569471609648366101593885546008609962622035890891754680149203464179471952105174480329668882489" - T[6, 6] = big"0.521751945274765285294609453181807034209434470364856664246194441011327338299794536726049398636575212016960129143954076748520870645966241492966592488607495009" - T[6, 7] = big"0.128071944635543894414114939510913357662538610722706228789484435811417614332529416514635125851744500940930818246509599119254761178392202724896572159336577251" - T[7, 1] = big"0.881391578353818376313498879127399181693003124999819194603124949551827789004545406999549226388170693806014968936224161749923163222614460424501073405017519348" - T[7, 2] = 1 - T[7, 3] = 0 - T[7, 4] = 1 - T[7, 5] = 0 - T[7, 6] = 1 - T[7, 7] = 0 - - RadauIIATableau{T1, T2}(T, TI, c, γ, α, β, e) +function RadauIIATableau(T1, T2, num_stages::Int) + tab = get(RadauIIATableauCache, (T1, T2, num_stages)) do + tab = generateRadauTableau(T1, T2, num_stages) + RadauIIATableauCache[T1, T2, num_stages] = tab + tab + end + return RadauIIATableau{T1, T2}(tab) end -import LinearAlgebra: eigen -import FastGaussQuadrature: gaussradau - -function RadauIIATableau(T1, T2, num_stages::Int) - c = reverse!(1 .- gaussradau(num_stages, T1)[1])./2 +function generateRadauTableau(T1, T2, num_stages::Int) + c = reverse!(1 .- gaussradau(num_stages, T1)[1]) ./ 2 if T1 == T2 c2 = c else - c2 = reverse!(1 .- gaussradau(num_stages, T2)[1])./2 + c2 = reverse!(1 .- gaussradau(num_stages, T2)[1]) ./ 2 end c_powers = Matrix{T1}(undef, num_stages, num_stages) - for i in 1 : num_stages + for i in 1:num_stages c_powers[i, 1] = 1 - for j in 2 : num_stages - c_powers[i,j] = c[i]*c_powers[i,j-1] + for j in 2:num_stages + c_powers[i, j] = c[i] * c_powers[i, j - 1] end end c_q = Matrix{T1}(undef, num_stages, num_stages) - for i in 1 : num_stages - for j in 1 : num_stages - c_q[i,j] = c_powers[i,j] * c[i] / j + for i in 1:num_stages + for j in 1:num_stages + c_q[i, j] = c_powers[i, j] * c[i] / j end end a = c_q / c_powers - local eigval, eigvec; + local eigval, eigvec try eigval, eigvec = eigen(a) catch @@ -549,8 +316,8 @@ function RadauIIATableau(T1, T2, num_stages::Int) end # α, β, and γ come from eigvals(inv(a)) which are equal to inv.(eivals(a)) eigval .= inv.(eigval) - α = [real(eigval[i]) for i in 1:2:num_stages-1] - β = [imag(eigval[i]) for i in 1:2:num_stages-1] + α = [real(eigval[i]) for i in 1:2:(num_stages - 1)] + β = [imag(eigval[i]) for i in 1:2:(num_stages - 1)] γ = real(eigval[num_stages]) T = Matrix{T1}(undef, num_stages, num_stages) @@ -561,10 +328,15 @@ function RadauIIATableau(T1, T2, num_stages::Int) @views T[:, 1] .= real.(eigvec[:, num_stages]) TI = inv(T) # TODO: figure out why all the order conditions are the same - A = c_powers'./(1:num_stages) + A = c_powers' ./ (1:num_stages) # TODO: figure out why these are the right b - b = vcat(-(num_stages)^2, -.5, zeros(num_stages - 2)) + b = vcat(-(num_stages)^2, -0.5, zeros(num_stages - 2)) e = A \ b tab = RadauIIATableau{T1, T2}(T, TI, c2, γ, α, β, e) end +const RadauIIATableauCache = Dict{ + Tuple{Type, Type, Int}, RadauIIATableau{T1, T2} where {T1, T2}}( + (Float64, Float64, 3) => generateRadauTableau(Float64, Float64, 3), + (Float64, Float64, 5) => generateRadauTableau(Float64, Float64, 5), + (Float64, Float64, 7) => generateRadauTableau(Float64, Float64, 7)) diff --git a/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl b/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl index dc4bbb1e88..2cf4563276 100644 --- a/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl +++ b/lib/OrdinaryDiffEqFIRK/src/integrator_interface.jl @@ -1,4 +1,5 @@ -@inline function DiffEqBase.get_tmp_cache(integrator, alg::Union{RadauIIA3, RadauIIA5, RadauIIA9, AdaptiveRadau}, +@inline function DiffEqBase.get_tmp_cache( + integrator, alg::Union{RadauIIA3, RadauIIA5, RadauIIA9, AdaptiveRadau}, cache::OrdinaryDiffEqMutableCache) (cache.tmp, cache.atmp) end diff --git a/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl b/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl index 15d7111499..7fd21b7d99 100644 --- a/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl +++ b/lib/OrdinaryDiffEqFIRK/test/ode_firk_tests.jl @@ -14,13 +14,28 @@ sim21 = test_convergence(1 ./ 2 .^ (2.5:-1:0.5), prob_ode_linear, RadauIIA9()) sim21 = test_convergence(1 ./ 2 .^ (2.5:-1:0.5), prob_ode_2Dlinear, RadauIIA9()) @test sim21.𝒪est[:final]≈8 atol=testTol -prob_ode_linear_big = remake(prob_ode_linear, u0 = big.(prob_ode_linear.u0), tspan = big.(prob_ode_linear.tspan)) -prob_ode_2Dlinear_big = remake(prob_ode_2Dlinear, u0 = big.(prob_ode_2Dlinear.u0), tspan = big.(prob_ode_2Dlinear.tspan)) +using GenericSchur -for i in [5, 9, 13], prob in [prob_ode_linear_big, prob_ode_2Dlinear_big] +prob_ode_linear_big = remake( + prob_ode_linear, u0 = big.(prob_ode_linear.u0), tspan = big.(prob_ode_linear.tspan)) +prob_ode_2Dlinear_big = remake(prob_ode_2Dlinear, u0 = big.(prob_ode_2Dlinear.u0), + tspan = big.(prob_ode_2Dlinear.tspan)) + +#non-threaded tests +for i in [5, 9, 13, 17, 21, 25], prob in [prob_ode_linear_big, prob_ode_2Dlinear_big] dts = 1 ./ 2 .^ (4.25:-1:0.25) local sim21 = test_convergence(dts, prob, AdaptiveRadau(min_order = i, max_order = i)) - @test sim21.𝒪est[:final]≈ i atol=testTol + @test sim21.𝒪est[:final]≈i atol=testTol +end +#threaded tests +using OrdinaryDiffEqCore +for i in [5, 9, 13, 17, 21, 25], prob in [prob_ode_linear_big, prob_ode_2Dlinear_big] + dts = 1 ./ 2 .^ (4.25:-1:0.25) + local sim21 = test_convergence(dts, + prob, + AdaptiveRadau(min_order = i, max_order = i, + threading = OrdinaryDiffEqCore.PolyesterThreads())) + @test sim21.𝒪est[:final]≈i atol=testTol end # test adaptivity diff --git a/lib/OrdinaryDiffEqFIRK/test/ode_high_order_firk_tests.jl b/lib/OrdinaryDiffEqFIRK/test/ode_high_order_firk_tests.jl deleted file mode 100644 index b78c50f7f1..0000000000 --- a/lib/OrdinaryDiffEqFIRK/test/ode_high_order_firk_tests.jl +++ /dev/null @@ -1,14 +0,0 @@ -using OrdinaryDiffEqFIRK, DiffEqDevTools, Test, LinearAlgebra -import ODEProblemLibrary: prob_ode_linear, prob_ode_2Dlinear - -using GenericSchur -testTol = 0.5 - -prob_ode_linear_big = remake(prob_ode_linear, u0 = big.(prob_ode_linear.u0), tspan = big.(prob_ode_linear.tspan)) -prob_ode_2Dlinear_big = remake(prob_ode_2Dlinear, u0 = big.(prob_ode_2Dlinear.u0), tspan = big.(prob_ode_2Dlinear.tspan)) - -for i in [17, 21], prob in [prob_ode_linear_big, prob_ode_2Dlinear_big] - dts = 1 ./ 2 .^ (4.25:-1:0.25) - sim21 = test_convergence(dts, prob, AdaptiveRadau(min_order = i, max_order = i)) - @test sim21.𝒪est[:final]≈ i atol=testTol -end diff --git a/lib/OrdinaryDiffEqFIRK/test/runtests.jl b/lib/OrdinaryDiffEqFIRK/test/runtests.jl index ec335b116b..39ede8c3b3 100644 --- a/lib/OrdinaryDiffEqFIRK/test/runtests.jl +++ b/lib/OrdinaryDiffEqFIRK/test/runtests.jl @@ -1,4 +1,3 @@ using SafeTestsets @time @safetestset "FIRK Tests" include("ode_firk_tests.jl") -@time @safetestset "High Order FIRK Tests" include("ode_high_order_firk_tests.jl") diff --git a/lib/OrdinaryDiffEqIMEXMultistep/Project.toml b/lib/OrdinaryDiffEqIMEXMultistep/Project.toml index ff8bd8f36b..afc8763088 100644 --- a/lib/OrdinaryDiffEqIMEXMultistep/Project.toml +++ b/lib/OrdinaryDiffEqIMEXMultistep/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqIMEXMultistep" uuid = "9f002381-b378-40b7-97a6-27a27c83f129" authors = ["ParamThakkar123 "] -version = "1.1.0" +version = "1.2.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" OrdinaryDiffEqCore = "bbf590c4-e513-4bbe-9b18-05decba2e5d8" @@ -12,11 +13,12 @@ OrdinaryDiffEqNonlinearSolve = "127b3ac7-2247-4354-8eb6-78cf4e7c58e8" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.14" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" OrdinaryDiffEqNonlinearSolve = "<0.0.1, 1" Random = "<0.0.1, 1" Reexport = "1.2.2" diff --git a/lib/OrdinaryDiffEqIMEXMultistep/src/OrdinaryDiffEqIMEXMultistep.jl b/lib/OrdinaryDiffEqIMEXMultistep/src/OrdinaryDiffEqIMEXMultistep.jl index 567e6b5eae..998c4a96f2 100644 --- a/lib/OrdinaryDiffEqIMEXMultistep/src/OrdinaryDiffEqIMEXMultistep.jl +++ b/lib/OrdinaryDiffEqIMEXMultistep/src/OrdinaryDiffEqIMEXMultistep.jl @@ -5,13 +5,14 @@ import OrdinaryDiffEqCore: alg_order, issplit, OrdinaryDiffEqNewtonAlgorithm, _u OrdinaryDiffEqMutableCache, @cache, alg_cache, initialize!, perform_step!, @unpack, full_cache, get_fsalfirstlast, - generic_solver_docstring + generic_solver_docstring, _bool_to_ADType, _process_AD_choice using FastBroadcast import OrdinaryDiffEqCore using OrdinaryDiffEqDifferentiation: dolinsolve using OrdinaryDiffEqNonlinearSolve: NLNewton, build_nlsolver, markfirststage!, nlsolve!, nlsolvefail, du_alias_or_new +import ADTypes: AutoForwardDiff, AbstractADType using Reexport @reexport using DiffEqBase diff --git a/lib/OrdinaryDiffEqIMEXMultistep/src/algorithms.jl b/lib/OrdinaryDiffEqIMEXMultistep/src/algorithms.jl index 69e0d7ab57..7f81a7c925 100644 --- a/lib/OrdinaryDiffEqIMEXMultistep/src/algorithms.jl +++ b/lib/OrdinaryDiffEqIMEXMultistep/src/algorithms.jl @@ -26,19 +26,24 @@ struct CNAB2{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function CNAB2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function CNAB2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + CNAB2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + _unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc generic_solver_docstring("Crank-Nicholson Leapfrong 2.", @@ -66,16 +71,21 @@ struct CNLF2{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function CNLF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function CNLF2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + CNLF2{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + _unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end diff --git a/lib/OrdinaryDiffEqLinear/src/linear_caches.jl b/lib/OrdinaryDiffEqLinear/src/linear_caches.jl index 14aaeb0692..c2867776d1 100644 --- a/lib/OrdinaryDiffEqLinear/src/linear_caches.jl +++ b/lib/OrdinaryDiffEqLinear/src/linear_caches.jl @@ -571,9 +571,10 @@ function _phiv_timestep_caches(u_prototype, maxiter::Int, p::Int) n = length(u_prototype) T = eltype(u_prototype) u = zero(u_prototype) # stores the current state - W = similar(u_prototype, n, p+1) # stores the w vectors - P = similar(u_prototype, n, p+2) # stores output from phiv! - Ks = KrylovSubspace{T,T,typeof(similar(u_prototype,size(u_prototype,1),2))}(n, maxiter) # stores output from arnoldi! + W = similar(u_prototype, n, p + 1) # stores the w vectors + P = similar(u_prototype, n, p + 2) # stores output from phiv! + Ks = KrylovSubspace{T, T, typeof(similar(u_prototype, size(u_prototype, 1), 2))}( + n, maxiter) # stores output from arnoldi! phiv_cache = PhivCache(u_prototype, maxiter, p + 1) # cache used by phiv! (need +1 for error estimation) return u, W, P, Ks, phiv_cache end @@ -591,7 +592,7 @@ function alg_cache(alg::LinearExponential, u, rate_prototype, ::Type{uEltypeNoUn if alg.krylov == :off KsCache = nothing elseif alg.krylov == :simple - Ks = KrylovSubspace{T,T,typeof(similar(u,size(u,1),2))}(n, m) + Ks = KrylovSubspace{T, T, typeof(similar(u, size(u, 1), 2))}(n, m) expv_cache = ExpvCache{T}(m) KsCache = (Ks, expv_cache) elseif alg.krylov == :adaptive diff --git a/lib/OrdinaryDiffEqLowStorageRK/test/ode_low_storage_rk_tests.jl b/lib/OrdinaryDiffEqLowStorageRK/test/ode_low_storage_rk_tests.jl index e4c5eece35..5bdc9109b1 100644 --- a/lib/OrdinaryDiffEqLowStorageRK/test/ode_low_storage_rk_tests.jl +++ b/lib/OrdinaryDiffEqLowStorageRK/test/ode_low_storage_rk_tests.jl @@ -101,13 +101,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -116,7 +116,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -146,13 +146,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -161,7 +161,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -191,13 +191,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -206,7 +206,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -236,13 +236,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -251,7 +251,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -281,13 +281,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -296,7 +296,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -326,13 +326,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -341,7 +341,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -371,13 +371,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -386,7 +386,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -416,13 +416,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -431,7 +431,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -461,13 +461,13 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 2 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg2, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -476,7 +476,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -499,7 +499,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -508,7 +508,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -531,7 +531,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -540,7 +540,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -593,7 +593,7 @@ test_problems_nonlinear_BigFloat = [prob_nonlinear_A, prob_nonlinear_B] save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 7 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -602,7 +602,7 @@ test_problems_nonlinear_BigFloat = [prob_nonlinear_A, prob_nonlinear_B] save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -628,7 +628,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 7 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -637,7 +637,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -663,7 +663,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 7 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -672,7 +672,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -698,7 +698,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 7 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -707,7 +707,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -733,7 +733,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 7 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -742,7 +742,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -768,7 +768,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 10 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 9 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -777,7 +777,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -803,7 +803,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 10 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 9 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -812,7 +812,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -838,7 +838,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 10 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 9 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -847,7 +847,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -873,7 +873,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 10 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 9 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -882,7 +882,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -908,7 +908,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 10 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 9 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -917,7 +917,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -943,7 +943,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 10 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 9 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -952,7 +952,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -978,7 +978,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 12 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 11 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -987,7 +987,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1013,7 +1013,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 12 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 11 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1022,7 +1022,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1048,7 +1048,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 12 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 11 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1057,7 +1057,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1083,7 +1083,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 12 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 11 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1092,7 +1092,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1118,7 +1118,7 @@ end save_end = false, save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 14 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 13 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1127,7 +1127,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1153,7 +1153,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1162,7 +1162,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1186,7 +1186,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1195,7 +1195,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1219,7 +1219,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1228,7 +1228,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1254,7 +1254,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1263,7 +1263,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1286,7 +1286,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1295,7 +1295,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1319,7 +1319,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1328,7 +1328,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1353,7 +1353,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1362,7 +1362,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1387,7 +1387,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1396,7 +1396,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1422,7 +1422,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1431,7 +1431,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1456,7 +1456,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1465,7 +1465,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1488,7 +1488,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1497,7 +1497,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1521,7 +1521,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1530,7 +1530,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1555,7 +1555,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1564,7 +1564,7 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end @@ -1587,7 +1587,7 @@ end save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 # test whether aliasing u0 is bad new_prob_ode_nonlinear_inplace = ODEProblem(prob_ode_nonlinear_inplace.f, [1.0], @@ -1596,6 +1596,6 @@ end save_start = false) sol_new = solve( new_prob_ode_nonlinear_inplace, alg, dt = 1.e-4, save_everystep = false, - save_start = false, alias_u0 = true) + save_start = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test sol_old[end] ≈ sol_new[end] end diff --git a/lib/OrdinaryDiffEqNonlinearSolve/Project.toml b/lib/OrdinaryDiffEqNonlinearSolve/Project.toml index 27bbe7ff3d..585a399d94 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/Project.toml +++ b/lib/OrdinaryDiffEqNonlinearSolve/Project.toml @@ -1,7 +1,7 @@ name = "OrdinaryDiffEqNonlinearSolve" uuid = "127b3ac7-2247-4354-8eb6-78cf4e7c58e8" authors = ["Chris Rackauckas ", "Yingbo Ma "] -version = "1.3.1" +version = "1.4.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -33,7 +33,7 @@ FastBroadcast = "0.3.5" FastClosures = "0.3.2" ForwardDiff = "0.10.36" LinearAlgebra = "<0.0.1, 1" -LinearSolve = "2.32.0" +LinearSolve = "2.32.0, 3" MuladdMacro = "0.2.4" NonlinearSolve = "3.14.0, 4" OrdinaryDiffEqCore = "1.13" @@ -52,9 +52,12 @@ julia = "1.10" [extras] DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d" +LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +ODEProblemLibrary = "fdc4e326-1af4-4b90-96e7-779fcce2daa5" +OrdinaryDiffEqSDIRK = "2d112036-d095-4a1e-ab9a-08536f3ecdbf" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["DiffEqDevTools", "Random", "SafeTestsets", "Test"] +test = ["DiffEqDevTools", "LineSearches", "ODEProblemLibrary", "OrdinaryDiffEqSDIRK", "Random", "SafeTestsets", "Test"] diff --git a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl index 593f27ee77..c83e781f1e 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/src/OrdinaryDiffEqNonlinearSolve.jl @@ -11,7 +11,8 @@ using SciMLBase: DAEFunction, DEIntegrator, NonlinearFunction, NonlinearProblem, import DiffEqBase import PreallocationTools using SimpleNonlinearSolve: SimpleTrustRegion, SimpleGaussNewton -using NonlinearSolve: FastShortcutNonlinearPolyalg, FastShortcutNLLSPolyalg, NewtonRaphson, step! +using NonlinearSolve: FastShortcutNonlinearPolyalg, FastShortcutNLLSPolyalg, NewtonRaphson, + step! using MuladdMacro, FastBroadcast import FastClosures: @closure using LinearAlgebra: UniformScaling, UpperTriangular diff --git a/lib/OrdinaryDiffEqNonlinearSolve/src/newton.jl b/lib/OrdinaryDiffEqNonlinearSolve/src/newton.jl index 994ecea696..d5e47246af 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/src/newton.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/src/newton.jl @@ -229,8 +229,9 @@ end reltol = reltol) end - if !SciMLBase.successful_retcode(linres.retcode) && linres.retcode != SciMLBase.ReturnCode.Default - return convert(eltype(atmp,),Inf) + if !SciMLBase.successful_retcode(linres.retcode) && + linres.retcode != SciMLBase.ReturnCode.Default + return convert(eltype(atmp,), Inf) end cache.linsolve = linres.cache diff --git a/lib/OrdinaryDiffEqNonlinearSolve/test/newton_tests.jl b/lib/OrdinaryDiffEqNonlinearSolve/test/newton_tests.jl index bbb78122c8..05c62cedbd 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/test/newton_tests.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/test/newton_tests.jl @@ -1,4 +1,6 @@ +using OrdinaryDiffEqNonlinearSolve: NLNewton using OrdinaryDiffEqCore +using OrdinaryDiffEqSDIRK using DiffEqDevTools using DiffEqBase using LineSearches @@ -12,5 +14,5 @@ for prob in (prob_ode_lorenz, prob_ode_orego) sol2 = solve(prob, Trapezoid(nlsolve = NLNewton(relax = BackTracking())), reltol = 1e-12, abstol = 1e-12) @test sol2.retcode == DiffEqBase.ReturnCode.Success - @test sol2.stats.nf <= sol1.stats.nf + @test abs(sol2.stats.nf - sol1.stats.nf) <= 20 end diff --git a/lib/OrdinaryDiffEqNonlinearSolve/test/runtests.jl b/lib/OrdinaryDiffEqNonlinearSolve/test/runtests.jl index 37192c8dbf..8f1738e67a 100644 --- a/lib/OrdinaryDiffEqNonlinearSolve/test/runtests.jl +++ b/lib/OrdinaryDiffEqNonlinearSolve/test/runtests.jl @@ -1,3 +1,3 @@ using SafeTestsets -@time @safetestset "Newton Tests" include("interface/newton_tests.jl") +@time @safetestset "Newton Tests" include("newton_tests.jl") diff --git a/lib/OrdinaryDiffEqPDIRK/Project.toml b/lib/OrdinaryDiffEqPDIRK/Project.toml index 2e1b6bb3b4..25e7e58663 100644 --- a/lib/OrdinaryDiffEqPDIRK/Project.toml +++ b/lib/OrdinaryDiffEqPDIRK/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqPDIRK" uuid = "5dd0a6cf-3d4b-4314-aa06-06d4e299bc89" authors = ["ParamThakkar123 "] -version = "1.1.1" +version = "1.2.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" @@ -15,12 +16,13 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" MuladdMacro = "0.2.4" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.14" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" OrdinaryDiffEqNonlinearSolve = "<0.0.1, 1" Polyester = "0.7.16" Random = "<0.0.1, 1" diff --git a/lib/OrdinaryDiffEqPDIRK/src/OrdinaryDiffEqPDIRK.jl b/lib/OrdinaryDiffEqPDIRK/src/OrdinaryDiffEqPDIRK.jl index 18a4e56205..393aade86a 100644 --- a/lib/OrdinaryDiffEqPDIRK/src/OrdinaryDiffEqPDIRK.jl +++ b/lib/OrdinaryDiffEqPDIRK/src/OrdinaryDiffEqPDIRK.jl @@ -5,7 +5,8 @@ import OrdinaryDiffEqCore: isfsal, alg_order, _unwrap_val, OrdinaryDiffEqMutableCache, constvalue, alg_cache, uses_uprev, @unpack, unwrap_alg, @cache, DEFAULT_PRECS, @threaded, initialize!, perform_step!, isthreaded, - full_cache, get_fsalfirstlast, differentiation_rk_docstring + full_cache, get_fsalfirstlast, differentiation_rk_docstring, + _bool_to_ADType, _process_AD_choice import StaticArrays: SVector import MuladdMacro: @muladd import FastBroadcast: @.. @@ -18,6 +19,8 @@ using OrdinaryDiffEqDifferentiation: dolinsolve using OrdinaryDiffEqNonlinearSolve: NLNewton, build_nlsolver, nlsolve!, nlsolvefail, markfirststage! +import ADTypes: AutoForwardDiff, AbstractADType + include("algorithms.jl") include("alg_utils.jl") include("pdirk_caches.jl") diff --git a/lib/OrdinaryDiffEqPDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqPDIRK/src/algorithms.jl index 0e93763cfd..d32f448193 100644 --- a/lib/OrdinaryDiffEqPDIRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqPDIRK/src/algorithms.jl @@ -28,13 +28,17 @@ struct PDIRK44{CS, AD, F, F2, P, FDT, ST, CJ, TO} <: precs::P extrapolant::Symbol threading::TO + autodiff::AD end -function PDIRK44(; chunk_size = Val{0}(), autodiff = true, standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function PDIRK44(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :constant, threading = true) - PDIRK44{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + PDIRK44{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(threading)}(linsolve, nlsolve, precs, - extrapolant, threading) + extrapolant, threading, AD_choice) end diff --git a/lib/OrdinaryDiffEqRKN/Project.toml b/lib/OrdinaryDiffEqRKN/Project.toml index 09dc6999b8..3cd5c9338c 100644 --- a/lib/OrdinaryDiffEqRKN/Project.toml +++ b/lib/OrdinaryDiffEqRKN/Project.toml @@ -23,7 +23,7 @@ Random = "<0.0.1, 1" RecursiveArrayTools = "3.27.0" Reexport = "1.2.2" SafeTestsets = "0.1.0" -Statistics = "1.11.1" +Statistics = "<0.0.1, 1" Test = "<0.0.1, 1" julia = "1.10" diff --git a/lib/OrdinaryDiffEqRosenbrock/Project.toml b/lib/OrdinaryDiffEqRosenbrock/Project.toml index 2769329879..bea0adb074 100644 --- a/lib/OrdinaryDiffEqRosenbrock/Project.toml +++ b/lib/OrdinaryDiffEqRosenbrock/Project.toml @@ -1,7 +1,7 @@ name = "OrdinaryDiffEqRosenbrock" uuid = "43230ef6-c299-4910-a778-202eb28ce4ce" authors = ["ParamThakkar123 "] -version = "1.3.1" +version = "1.5.0" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" @@ -23,19 +23,19 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69" Static = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" [compat] -ADTypes = "1.7.1" +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" FiniteDiff = "2.24.0" ForwardDiff = "0.10.36" LinearAlgebra = "<0.0.1, 1" -LinearSolve = "2.32.0" +LinearSolve = "2.32.0, 3" MacroTools = "0.5.13" MuladdMacro = "0.2.4" ODEProblemLibrary = "0.1.8" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.14" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" Polyester = "0.7.16" PrecompileTools = "1.2.1" Preferences = "1.4.3" diff --git a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl index d5aa1d363f..bf268b58a4 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl @@ -12,7 +12,8 @@ import OrdinaryDiffEqCore: alg_order, alg_adaptive_order, isWmethod, isfsal, _un constvalue, only_diagonal_mass_matrix, calculate_residuals, has_stiff_interpolation, ODEIntegrator, resize_non_user_cache!, _ode_addsteps!, full_cache, - DerivativeOrderNotPossibleError + DerivativeOrderNotPossibleError, _bool_to_ADType, + _process_AD_choice using MuladdMacro, FastBroadcast, RecursiveArrayTools import MacroTools using MacroTools: @capture @@ -22,7 +23,7 @@ import LinearSolve: UniformScaling import ForwardDiff using FiniteDiff using LinearAlgebra: mul!, diag, diagm, I, Diagonal, norm -import ADTypes: AutoForwardDiff +import ADTypes: AutoForwardDiff, AbstractADType import OrdinaryDiffEqCore using OrdinaryDiffEqDifferentiation: TimeDerivativeWrapper, TimeGradientWrapper, @@ -48,7 +49,7 @@ function rosenbrock_wolfbrandt_docstring(description::String, keyword_default = """ chunk_size = Val{0}(), standardtag = Val{true}(), - autodiff = Val{true}(), + autodiff = AutoForwardDiff(), concrete_jac = nothing, diff_type = Val{:central}, linsolve = nothing, @@ -56,22 +57,21 @@ function rosenbrock_wolfbrandt_docstring(description::String, """ * extra_keyword_default keyword_default_description = """ - - `chunk_size`: The chunk size used with ForwardDiff.jl. Defaults to `Val{0}()` - and thus uses the internal ForwardDiff.jl algorithm for the choice. - `standardtag`: Specifies whether to use package-specific tags instead of the ForwardDiff default function-specific tags. For more information, see [this blog post](https://www.stochasticlifestyle.com/improved-forwarddiff-jl-stacktraces-with-package-tags/). Defaults to `Val{true}()`. - - `autodiff`: Specifies whether to use automatic differentiation via + - `autodiff`: Uses [ADTypes.jl](https://sciml.github.io/ADTypes.jl/stable/) + to specify whether to use automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) or finite - differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). - Defaults to `Val{true}()` for automatic differentiation. + differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). + Defaults to `AutoForwardDiff()` for automatic differentiation, which by default uses + `chunksize = 0`, and thus uses the internal ForwardDiff.jl algorithm for the choice. + To use `FiniteDiff.jl`, the `AutoFiniteDiff()` ADType can be used, which has a keyword argument + `fdtype` with default value `Val{:forward}()`, and alternatives `Val{:central}()` and `Val{:complex}()`. - `concrete_jac`: Specifies whether a Jacobian should be constructed. Defaults to `nothing`, which means it will be chosen true/false depending on circumstances of the solver, such as whether a Krylov subspace method is used for `linsolve`. - - `diff_type`: The type of differentiation used in FiniteDiff.jl if `autodiff=false`. - Defaults to `Val{:forward}`, with alternatives of `Val{:central}` and - `Val{:complex}`. - `linsolve`: Any [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) compatible linear solver. For example, to use [KLU.jl](https://github.com/JuliaSparse/KLU.jl), specify `$name(linsolve = KLUFactorization()`). @@ -130,22 +130,21 @@ function rosenbrock_docstring(description::String, extra_keyword_default = "", with_step_limiter = false) keyword_default = """ - - `chunk_size`: The chunk size used with ForwardDiff.jl. Defaults to `Val{0}()` - and thus uses the internal ForwardDiff.jl algorithm for the choice. - `standardtag`: Specifies whether to use package-specific tags instead of the ForwardDiff default function-specific tags. For more information, see [this blog post](https://www.stochasticlifestyle.com/improved-forwarddiff-jl-stacktraces-with-package-tags/). Defaults to `Val{true}()`. - - `autodiff`: Specifies whether to use automatic differentiation via + - `autodiff`: Uses [ADTypes.jl](https://sciml.github.io/ADTypes.jl/stable/) + to specify whether to use automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) or finite - differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). - Defaults to `Val{true}()` for automatic differentiation. + differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). + Defaults to `AutoForwardDiff()` for automatic differentiation, which by default uses + `chunksize = 0`, and thus uses the internal ForwardDiff.jl algorithm for the choice. + To use `FiniteDiff.jl`, the `AutoFiniteDiff()` ADType can be used, which has a keyword argument + `fdtype` with default value `Val{:forward}()`, and alternatives `Val{:central}()` and `Val{:complex}()`. - `concrete_jac`: Specifies whether a Jacobian should be constructed. Defaults to `nothing`, which means it will be chosen true/false depending on circumstances of the solver, such as whether a Krylov subspace method is used for `linsolve`. - - `diff_type`: The type of differentiation used in FiniteDiff.jl if `autodiff=false`. - Defaults to `Val{:forward}`, with alternatives of `Val{:central}` and - `Val{:complex}`. - `linsolve`: Any [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) compatible linear solver. For example, to use [KLU.jl](https://github.com/JuliaSparse/KLU.jl), specify `$name(linsolve = KLUFactorization()`). diff --git a/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl b/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl index 2ad10b28c8..98f2a30b3c 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl @@ -110,17 +110,19 @@ for Alg in [ precs::P step_limiter!::StepLimiter stage_limiter!::StageLimiter + autodiff::AD end - function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), + function $Alg(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, linsolve = 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + $Alg{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + stage_limiter!, AD_choice) end end end @@ -128,15 +130,18 @@ struct GeneralRosenbrock{CS, AD, F, ST, CJ, TabType} <: OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, Val{:forward}, ST, CJ} tableau::TabType factorization::F + autodiff::AD end -function GeneralRosenbrock(; chunk_size = Val{0}(), autodiff = true, +function GeneralRosenbrock(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, factorization = lu!, tableau = ROSENBROCK_DEFAULT_TABLEAU) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + GeneralRosenbrock{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(factorization), + _unwrap_val(chunk_size), typeof(AD_choice), typeof(factorization), _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(tableau)}(tableau, - factorization) + factorization, AD_choice) end @doc rosenbrock_wolfbrandt_docstring( @@ -151,16 +156,19 @@ struct RosenbrockW6S4OS{CS, AD, F, P, FDT, ST, CJ} <: OrdinaryDiffEqRosenbrockAlgorithm{CS, AD, FDT, ST, CJ} linsolve::F precs::P + autodiff::AD end -function RosenbrockW6S4OS(; chunk_size = Val{0}(), autodiff = true, +function RosenbrockW6S4OS(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, diff_type = Val{:central}, linsolve = nothing, precs = DEFAULT_PRECS) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + RosenbrockW6S4OS{_unwrap_val(chunk_size), - _unwrap_val(autodiff), typeof(linsolve), typeof(precs), diff_type, + typeof(AD_choice), typeof(linsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, - precs) + precs, AD_choice) end for Alg in [ @@ -189,14 +197,17 @@ for Alg in [ OrdinaryDiffEqRosenbrockAdaptiveAlgorithm{CS, AD, FDT, ST, CJ} linsolve::F precs::P + autodiff::AD end - function $Alg(; chunk_size = Val{0}(), autodiff = Val{true}(), + function $Alg(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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), + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + $Alg{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, - precs) + precs, AD_choice) end end end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl b/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl index 74a0ad57c6..1b9ff7a936 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/generic_rosenbrock.jl @@ -950,8 +950,9 @@ An Order 2/3 L-Stable Rosenbrock-W method for stiff ODEs and DAEs in mass matrix """, "Rodas23W", references = """ -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate for dense output and Julia implementation, - In progress. +- 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) Rodas23W @@ -1035,9 +1036,8 @@ references = """ """, "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 +- Sandu, Verwer, Van Loon, Carmichael, Potra, Dabdub, Seinfeld, Benchmarking stiff ode solvers for atmospheric chemistry problems-I. + implicit vs explicit, Atmospheric Environment, 31(19), 3151-3166, 1997. """, with_step_limiter=true) Rodas3 @@ -1048,9 +1048,9 @@ and additional error test for interpolation. Keeps accuracy on discretizations o """, "Rodas3P", references = """ -- Steinebach G., Rodas23W / Rodas32P - a Rosenbrock-type method for DAEs with additional error estimate - for dense output and Julia implementation, - In progress. +- 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) Rodas3P @@ -1096,9 +1096,10 @@ 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. +- Steinebach, G., Rentrop, P., An adaptive method of lines approach for modelling flow and transport in rivers. + Adaptive method of lines , Wouver, A. Vande, Sauces, Ph., Schiesser, W.E. (ed.),S. 181-205,Chapman & Hall/CRC, 2001, +- Steinebach, G., Oder-reduction of ROW-methods for DAEs and method of lines applications. + Preprint-Nr. 1741, FB Mathematik, TH Darmstadt, 1995. """, with_step_limiter=true) Rodas4P @@ -1110,9 +1111,8 @@ 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. +- Steinebach G., Improvement of Rosenbrock-Wanner Method RODASP, In: Reis T., Grundel S., Schöps S. (eds) + Progress in Differential-Algebraic Equations II. Differential-Algebraic Equations Forum. Springer, Cham., 165-184, 2020. """, with_step_limiter=true) Rodas4P2 @@ -1143,8 +1143,7 @@ with_step_limiter=true) Rodas5P @doc rosenbrock_wolfbrandt_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. +Variant of Ropdas5P with additional residual control. """, "Rodas5Pr", references = """ @@ -1156,8 +1155,7 @@ with_step_limiter=true) Rodas5Pr @doc rosenbrock_wolfbrandt_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. +Variant of Ropdas5P with modified embedded scheme. """, "Rodas5Pe", references = """ diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl index 33fc5dcd2b..34fa9e3dd7 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl @@ -48,7 +48,8 @@ function full_cache(c::RosenbrockCache) c.ks..., c.fsalfirst, c.fsallast, c.dT, c.tmp, c.atmp, c.weight, c.linsolve_tmp] end -struct RosenbrockCombinedConstantCache{TF, UF, Tab, JType, WType, F, AD} <: RosenbrockConstantCache +struct RosenbrockCombinedConstantCache{TF, UF, Tab, JType, WType, F, AD} <: + RosenbrockConstantCache tf::TF uf::UF tab::Tab @@ -723,7 +724,8 @@ tabtype(::Rodas5P) = Rodas5PTableau tabtype(::Rodas5Pr) = Rodas5PTableau tabtype(::Rodas5Pe) = Rodas5PTableau -function alg_cache(alg::Union{Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr}, +function alg_cache( + alg::Union{Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr}, u, rate_prototype, ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, @@ -739,12 +741,12 @@ function alg_cache(alg::Union{Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas5, Rodas5 alg_autodiff(alg), size(tab.H, 1)) end -function alg_cache(alg::Union{Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr}, +function alg_cache( + alg::Union{Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas5, 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} - tab = tabtype(alg)(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) # Initialize vectors dense = [zero(rate_prototype) for _ in 1:size(tab.H, 1)] @@ -792,7 +794,6 @@ function alg_cache(alg::Union{Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas5, Rodas5 alg.step_limiter!, alg.stage_limiter!, size(tab.H, 1)) end - function get_fsalfirstlast( cache::Union{Rosenbrock23Cache, Rosenbrock32Cache, Rosenbrock33Cache, Rosenbrock34Cache, diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl index 003595567e..365b15e10f 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_interpolants.jl @@ -49,7 +49,7 @@ end cache::Union{Rosenbrock23Cache, Rosenbrock32Cache}, idxs::Nothing, T::Type{Val{0}}, differential_vars) @rosenbrock2332pre0 - @inbounds @.. y₀+dt * (c1 * k[1] + c2 * k[2]) + @inbounds @.. y₀ + dt * (c1 * k[1] + c2 * k[2]) end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, @@ -57,7 +57,7 @@ end Rosenbrock32ConstantCache, Rosenbrock32Cache }, idxs, T::Type{Val{0}}, differential_vars) @rosenbrock2332pre0 - @.. y₀[idxs]+dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) + @.. y₀[idxs] + dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, @@ -66,7 +66,7 @@ end Rosenbrock32ConstantCache, Rosenbrock32Cache }, idxs::Nothing, T::Type{Val{0}}, differential_vars) @rosenbrock2332pre0 - @inbounds @.. out=y₀ + dt * (c1 * k[1] + c2 * k[2]) + @inbounds @.. out = y₀ + dt * (c1 * k[1] + c2 * k[2]) out end @@ -76,7 +76,7 @@ end Rosenbrock32ConstantCache, Rosenbrock32Cache }, idxs, T::Type{Val{0}}, differential_vars) @rosenbrock2332pre0 - @views @.. out=y₀[idxs] + dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) + @views @.. out = y₀[idxs] + dt * (c1 * k[1][idxs] + c2 * k[2][idxs]) out end @@ -92,7 +92,7 @@ end Rosenbrock32ConstantCache, Rosenbrock32Cache }, idxs::Nothing, T::Type{Val{1}}, differential_vars) @rosenbrock2332pre1 - @.. c1diff * k[1]+c2diff * k[2] + @.. c1diff * k[1] + c2diff * k[2] end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, @@ -100,7 +100,7 @@ end Rosenbrock32ConstantCache, Rosenbrock32Cache }, idxs, T::Type{Val{1}}, differential_vars) @rosenbrock2332pre1 - @.. c1diff * k[1][idxs]+c2diff * k[2][idxs] + @.. c1diff * k[1][idxs] + c2diff * k[2][idxs] end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, @@ -109,7 +109,7 @@ end Rosenbrock32ConstantCache, Rosenbrock32Cache }, idxs::Nothing, T::Type{Val{1}}, differential_vars) @rosenbrock2332pre1 - @.. out=c1diff * k[1] + c2diff * k[2] + @.. out = c1diff * k[1] + c2diff * k[2] out end @@ -119,7 +119,7 @@ end Rosenbrock32ConstantCache, Rosenbrock32Cache }, idxs, T::Type{Val{1}}, differential_vars) @rosenbrock2332pre1 - @views @.. out=c1diff * k[1][idxs] + c2diff * k[2][idxs] + @views @.. out = c1diff * k[1][idxs] + c2diff * k[2][idxs] out end @@ -128,108 +128,132 @@ From MATLAB ODE Suite by Shampine """ @muladd function _ode_interpolant( - Θ, dt, y₀, y₁, k, cache::Union{RosenbrockCombinedConstantCache, Rodas23WConstantCache, Rodas3PConstantCache, RosenbrockCache, Rodas23WCache, Rodas3PCache}, + Θ, dt, + y₀, + y₁, + k, + cache::Union{RosenbrockCombinedConstantCache, Rodas23WConstantCache, + Rodas3PConstantCache, RosenbrockCache, Rodas23WCache, Rodas3PCache}, idxs::Nothing, T::Type{Val{0}}, differential_vars) Θ1 = 1 - Θ if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @.. Θ1 * y₀+Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) + @.. Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) else - @.. Θ1 * y₀+Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) + @.. Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) end end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, + cache::Union{ + RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, idxs, T::Type{Val{0}}, differential_vars) Θ1 = 1 - Θ if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @views @.. Θ1 * y₀[idxs]+Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) + @views @.. Θ1 * y₀[idxs] + Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) else - @views @.. Θ1 * y₀[idxs]+Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) + @views @.. Θ1 * y₀[idxs] + + Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) end end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, + cache::Union{ + RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, idxs::Nothing, T::Type{Val{0}}, differential_vars) Θ1 = 1 - Θ if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @.. out=Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) + @.. out = Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * k[2])) else - @.. out=Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) + @.. out = Θ1 * y₀ + Θ * (y₁ + Θ1 * (k[1] + Θ * (k[2] + Θ * k[3]))) end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, + cache::Union{ + RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, idxs, T::Type{Val{0}}, differential_vars) Θ1 = 1 - Θ if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @views @.. out=Θ1 * y₀[idxs] + Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) + @views @.. out = Θ1 * y₀[idxs] + Θ * (y₁[idxs] + Θ1 * (k[1][idxs] + Θ * k[2][idxs])) else - @views @.. out=Θ1 * y₀[idxs]+Θ * (y₁[idxs] + - Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) + @views @.. out = Θ1 * y₀[idxs] + + Θ * (y₁[idxs] + + Θ1 * (k[1][idxs] + Θ * (k[2][idxs] + Θ * k[3][idxs]))) end out end # First Derivative @muladd function _ode_interpolant( - Θ, dt, y₀, y₁, k, cache::Union{RosenbrockCache, Rodas23WCache, Rodas3PCache, RosenbrockCombinedConstantCache, Rodas23WConstantCache, Rodas3PConstantCache}, + Θ, dt, + y₀, + y₁, + k, + cache::Union{ + RosenbrockCache, Rodas23WCache, Rodas3PCache, RosenbrockCombinedConstantCache, + Rodas23WConstantCache, Rodas3PConstantCache}, idxs::Nothing, T::Type{Val{1}}, differential_vars) if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @.. (k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁)/dt + @.. (k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁) / dt else - @.. (k[1] + Θ * (-2 * k[1] + 2 * k[2] + - Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - - y₀ + y₁)/dt + @.. (k[1] + Θ * (-2 * k[1] + 2 * k[2] + + Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - + y₀ + y₁) / dt end end @muladd function _ode_interpolant(Θ, dt, y₀, y₁, k, - cache::Union{RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, + cache::Union{ + RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, idxs, T::Type{Val{1}}, differential_vars) if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @views @.. (k[1][idxs] + Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] - 3 * k[2][idxs] * Θ) - - y₀[idxs] + y₁[idxs])/dt + @views @.. (k[1][idxs] + + Θ * (-2 * k[1][idxs] + 2 * k[2][idxs] - 3 * k[2][idxs] * Θ) - + y₀[idxs] + y₁[idxs]) / dt else - @views @.. (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 + @views @.. (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 end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, + cache::Union{ + RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, idxs::Nothing, T::Type{Val{1}}, differential_vars) if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @.. out=(k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁) / dt + @.. out = (k[1] + Θ * (-2 * k[1] + 2 * k[2] - 3 * k[2] * Θ) - y₀ + y₁) / dt else - @.. out=(k[1] + Θ * (-2 * k[1] + 2 * k[2] + - Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + y₁) / dt + @.. out = (k[1] + + Θ * (-2 * k[1] + 2 * k[2] + + Θ * (-3 * k[2] + 3 * k[3] - 4 * Θ * k[3])) - y₀ + y₁) / dt end out end @muladd function _ode_interpolant!(out, Θ, dt, y₀, y₁, k, - cache::Union{RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, + cache::Union{ + RosenbrockCombinedConstantCache, RosenbrockCache, Rodas23WConstantCache, Rodas23WCache, Rodas3PConstantCache, Rodas3PCache}, idxs, T::Type{Val{1}}, differential_vars) if !hasproperty(cache, :interp_order) || cache.interp_order == 2 - @views @.. out=(k[1][idxs] + - Θ * - (-2 * k[1][idxs] + 2 * k[2][idxs] - - 3 * k[2][idxs] * Θ) - - y₀[idxs] + y₁[idxs]) / dt + @views @.. out = (k[1][idxs] + + Θ * + (-2 * k[1][idxs] + 2 * k[2][idxs] - + 3 * k[2][idxs] * Θ) - + y₀[idxs] + y₁[idxs]) / dt else @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])) - + (-3 * k[2][idxs] + 3 * k[3][idxs] - + 4 * Θ * k[3][idxs])) - y₀[idxs] + y₁[idxs]) / dt end out diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl index 1414a93f92..773f1eb7f5 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_perform_step.jl @@ -1206,15 +1206,16 @@ function initialize!(integrator, cache::RosenbrockCombinedConstantCache) integrator.kshortsize = size(cache.tab.H, 1) integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) # Avoid undefined entries if k is an array of arrays - for i in 1:integrator.kshortsize + for i in 1:(integrator.kshortsize) integrator.k[i] = zero(integrator.u) end end -@muladd function perform_step!(integrator, cache::RosenbrockCombinedConstantCache, repeat_step = false) - (;t, dt, uprev, u, f, p) = integrator - (;tf, uf) = cache - (;A, C, gamma, c, d, H) = cache.tab +@muladd function perform_step!( + integrator, cache::RosenbrockCombinedConstantCache, repeat_step = false) + (; t, dt, uprev, u, f, p) = integrator + (; tf, uf) = cache + (; A, C, gamma, c, d, H) = cache.tab # Precalculations dtC = C ./ dt @@ -1287,20 +1288,20 @@ end end end 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) - OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) - if mass_matrix === I - du2 = du1 - du - else - du2 = mass_matrix * du1 - du - end - EEst = norm(du2) / norm(integrator.opts.abstol .+ integrator.opts.reltol .* k2) - integrator.EEst = max(EEst, integrator.EEst) - end + (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) + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) + if mass_matrix === I + du2 = du1 - du + else + du2 = mass_matrix * du1 - du + end + EEst = norm(du2) / norm(integrator.opts.abstol .+ integrator.opts.reltol .* k2) + integrator.EEst = max(EEst, integrator.EEst) + end end integrator.u = u @@ -1310,7 +1311,7 @@ end function initialize!(integrator, cache::RosenbrockCache) integrator.kshortsize = size(cache.tab.H, 1) resize!(integrator.k, integrator.kshortsize) - for i in 1:integrator.kshortsize + for i in 1:(integrator.kshortsize) integrator.k[i] = cache.dense[i] end end @@ -1389,9 +1390,9 @@ end if integrator.opts.adaptive if (integrator.alg isa Rodas5Pe) @.. du = 0.2606326497975715 * ks[1] - 0.005158627295444251 * ks[2] + - 1.3038988631109731 * ks[3] + 1.235000722062074 * ks[4] + - -0.7931985603795049 * ks[5] - 1.005448461135913 * ks[6] - - 0.18044626132120234 * ks[7] + 0.17051519239113755 * ks[8] + 1.3038988631109731 * ks[3] + 1.235000722062074 * ks[4] + + -0.7931985603795049 * ks[5] - 1.005448461135913 * ks[6] - + 0.18044626132120234 * ks[7] + 0.17051519239113755 * ks[8] end calculate_residuals!(atmp, ks[end], uprev, u, integrator.opts.abstol, integrator.opts.reltol, integrator.opts.internalnorm, t) @@ -1408,21 +1409,23 @@ end end end if (integrator.alg isa Rodas5Pr) && integrator.opts.adaptive && - (integrator.EEst < 1.0) - ks[2] = 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, ks[2], p, t + dt / 2) - OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) - if mass_matrix === I - @.. du2 = du1 - du - else - mul!(_vec(du2), mass_matrix, _vec(du1)) - @.. du2 -= du - end - EEst = norm(du2) / norm(integrator.opts.abstol .+ integrator.opts.reltol .* ks[2]) - integrator.EEst = max(EEst, integrator.EEst) - end + (integrator.EEst < 1.0) + ks[2] = 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, ks[2], p, t + dt / 2) + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) + if mass_matrix === I + @.. du2 = du1 - du + else + mul!(_vec(du2), mass_matrix, _vec(du1)) + @.. du2 -= du + end + EEst = norm(du2) / + norm(integrator.opts.abstol .+ integrator.opts.reltol .* ks[2]) + integrator.EEst = max(EEst, integrator.EEst) + end end cache.linsolve = linres.cache end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl index 7ed62e5847..9e15ea1ae8 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_tableaus.jl @@ -236,22 +236,18 @@ function Rodas4Tableau(T, T2) #BET2P=0.0317D0 #BET3P=0.0635D0 #BET4P=0.3438D0 - A = T[ - 0 0 0 0 0 0 - 1.544 0 0 0 0 0 - 0.9466785280815826 0.2557011698983284 0 0 0 0 - 3.314825187068521 2.896124015972201 0.9986419139977817 0 0 0 - 1.221224509226641 6.019134481288629 12.53708332932087 -0.6878860361058950 0 0 - 1.221224509226641 6.019134481288629 12.53708332932087 -0.6878860361058950 1 0 - ] - C = T[ - 0 0 0 0 0 - -5.6688 0 0 0 0 - -2.430093356833875 -0.2063599157091915 0 0 0 - -0.1073529058151375 -9.594562251023355 -20.47028614809616 0 0 - 7.496443313967647 -10.24680431464352 -33.99990352819905 11.70890893206160 0 - 8.083246795921522 -7.981132988064893 -31.52159432874371 16.31930543123136 -6.058818238834054 - ] + A = T[0 0 0 0 0 0 + 1.544 0 0 0 0 0 + 0.9466785280815826 0.2557011698983284 0 0 0 0 + 3.314825187068521 2.896124015972201 0.9986419139977817 0 0 0 + 1.221224509226641 6.019134481288629 12.53708332932087 -0.6878860361058950 0 0 + 1.221224509226641 6.019134481288629 12.53708332932087 -0.6878860361058950 1 0] + C = T[0 0 0 0 0 + -5.6688 0 0 0 0 + -2.430093356833875 -0.2063599157091915 0 0 0 + -0.1073529058151375 -9.594562251023355 -20.47028614809616 0 0 + 7.496443313967647 -10.24680431464352 -33.99990352819905 11.70890893206160 0 + 8.083246795921522 -7.981132988064893 -31.52159432874371 16.31930543123136 -6.058818238834054] c = T2[0, 0.386, 0.21, 0.63, 1, 1] d = T[0.25, -0.1043, 0.1035, -0.0362, 0, 0] H = T[10.12623508344586 -7.487995877610167 -34.80091861555747 -7.992771707568823 1.025137723295662 0 @@ -327,34 +323,29 @@ end function Rodas5Tableau(T, T2) gamma = convert(T2, 0.19) - A = T[ - 0 0 0 0 0 0 0 0 - 2.0 0 0 0 0 0 0 0 - 3.040894194418781 1.041747909077569 0 0 0 0 0 0 - 2.576417536461461 1.622083060776640 -0.9089668560264532 0 0 0 0 0 - 2.760842080225597 1.446624659844071 -0.3036980084553738 0.2877498600325443 0 0 0 0 - -14.09640773051259 6.925207756232704 -41.47510893210728 2.343771018586405 24.13215229196062 0 0 0 - -14.09640773051259 6.925207756232704 -41.47510893210728 2.343771018586405 24.13215229196062 1 0 0 - -14.09640773051259 6.925207756232704 -41.47510893210728 2.343771018586405 24.13215229196062 1 1 0 - ] - C = T[ - 0 0 0 0 0 0 0 - -10.31323885133993 0 0 0 0 0 0 - -21.04823117650003 -7.234992135176716 0 0 0 0 0 - 32.22751541853323 -4.943732386540191 19.44922031041879 0 0 0 0 - -20.69865579590063 -8.816374604402768 1.260436877740897 -0.7495647613787146 0 0 0 - -46.22004352711257 -17.49534862857472 -289.6389582892057 93.60855400400906 318.3822534212147 0 0 - 34.20013733472935 -14.15535402717690 57.82335640988400 25.83362985412365 1.408950972071624 -6.551835421242162 0 - 42.57076742291101 -13.80770672017997 93.98938432427124 18.77919633714503 -31.58359187223370 -6.685968952921985 -5.810979938412932 - ] + A = T[0 0 0 0 0 0 0 0 + 2.0 0 0 0 0 0 0 0 + 3.040894194418781 1.041747909077569 0 0 0 0 0 0 + 2.576417536461461 1.622083060776640 -0.9089668560264532 0 0 0 0 0 + 2.760842080225597 1.446624659844071 -0.3036980084553738 0.2877498600325443 0 0 0 0 + -14.09640773051259 6.925207756232704 -41.47510893210728 2.343771018586405 24.13215229196062 0 0 0 + -14.09640773051259 6.925207756232704 -41.47510893210728 2.343771018586405 24.13215229196062 1 0 0 + -14.09640773051259 6.925207756232704 -41.47510893210728 2.343771018586405 24.13215229196062 1 1 0] + C = T[0 0 0 0 0 0 0 + -10.31323885133993 0 0 0 0 0 0 + -21.04823117650003 -7.234992135176716 0 0 0 0 0 + 32.22751541853323 -4.943732386540191 19.44922031041879 0 0 0 0 + -20.69865579590063 -8.816374604402768 1.260436877740897 -0.7495647613787146 0 0 0 + -46.22004352711257 -17.49534862857472 -289.6389582892057 93.60855400400906 318.3822534212147 0 0 + 34.20013733472935 -14.15535402717690 57.82335640988400 25.83362985412365 1.408950972071624 -6.551835421242162 0 + 42.57076742291101 -13.80770672017997 93.98938432427124 18.77919633714503 -31.58359187223370 -6.685968952921985 -5.810979938412932] c = T2[0, 0.38, 0.3878509998321533, 0.4839718937873840, 0.4570477008819580, 1, 1, 1] - d = T[gamma, -0.1823079225333714636, -0.319231832186874912, 0.3449828624725343, -0.377417564392089818, 0, 0, 0] + d = T[gamma, -0.1823079225333714636, -0.319231832186874912, + 0.3449828624725343, -0.377417564392089818, 0, 0, 0] - H = T[ - 27.354592673333357 -6.925207756232857 26.40037733258859 0.5635230501052979 -4.699151156849391 -1.6008677469422725 -1.5306074446748028 -1.3929872940716344 - 44.19024239501722 1.3677947663381929e-13 202.93261852171622 -35.5669339789154 -181.91095152160645 3.4116351403665033 2.5793540257308067 2.2435122582734066 - -44.0988150021747 -5.755396159656812e-13 -181.26175034586677 56.99302194811676 183.21182741427398 -7.480257918273637 -5.792426076169686 -5.32503859794143 - ] + H = T[27.354592673333357 -6.925207756232857 26.40037733258859 0.5635230501052979 -4.699151156849391 -1.6008677469422725 -1.5306074446748028 -1.3929872940716344 + 44.19024239501722 1.3677947663381929e-13 202.93261852171622 -35.5669339789154 -181.91095152160645 3.4116351403665033 2.5793540257308067 2.2435122582734066 + -44.0988150021747 -5.755396159656812e-13 -181.26175034586677 56.99302194811676 183.21182741427398 -7.480257918273637 -5.792426076169686 -5.32503859794143] # println("---Rodas5---") #= @@ -385,33 +376,29 @@ end function Rodas5PTableau(T, T2) gamma = convert(T2, 0.21193756319429014) - A = T[ - 0 0 0 0 0 0 0 0 - 3.0 0 0 0 0 0 0 0 - 2.849394379747939 0.45842242204463923 0 0 0 0 0 0 - -6.954028509809101 2.489845061869568 -10.358996098473584 0 0 0 0 0 - 2.8029986275628964 0.5072464736228206 -0.3988312541770524 -0.04721187230404641 0 0 0 0 - -7.502846399306121 2.561846144803919 -11.627539656261098 -0.18268767659942256 0.030198172008377946 0 0 0 - -7.502846399306121 2.561846144803919 -11.627539656261098 -0.18268767659942256 0.030198172008377946 1 0 0 - -7.502846399306121 2.561846144803919 -11.627539656261098 -0.18268767659942256 0.030198172008377946 1 1 0 - ] - C = T[ - 0 0 0 0 0 0 0 - -14.155112264123755 0 0 0 0 0 0 - -17.97296035885952 -2.859693295451294 0 0 0 0 0 - 147.12150275711716 -1.41221402718213 71.68940251302358 0 0 0 0 - 165.43517024871676 -0.4592823456491126 42.90938336958603 -5.961986721573306 0 0 0 - 24.854864614690072 -3.0009227002832186 47.4931110020768 5.5814197821558125 -0.6610691825249471 0 0 - 30.91273214028599 -3.1208243349937974 77.79954646070892 34.28646028294783 -19.097331116725623 -28.087943162872662 0 - 37.80277123390563 -3.2571969029072276 112.26918849496327 66.9347231244047 -40.06618937091002 -54.66780262877968 -9.48861652309627 - ] - c = T2[0, 0.6358126895828704, 0.4095798393397535, 0.9769306725060716, 0.4288403609558664, 1, 1, 1] - d = T[0.21193756319429014, -0.42387512638858027, -0.3384627126235924, 1.8046452872882734, 2.325825639765069, 0, 0, 0] - H = T[ - 25.948786856663858 -2.5579724845846235 10.433815404888879 -2.3679251022685204 0.524948541321073 1.1241088310450404 0.4272876194431874 -0.17202221070155493 - -9.91568850695171 -0.9689944594115154 3.0438037242978453 -24.495224566215796 20.176138334709044 15.98066361424651 -6.789040303419874 -6.710236069923372 - 11.419903575922262 2.8879645146136994 72.92137995996029 80.12511834622643 -52.072871366152654 -59.78993625266729 -0.15582684282751913 4.883087185713722 - ] + A = T[0 0 0 0 0 0 0 0 + 3.0 0 0 0 0 0 0 0 + 2.849394379747939 0.45842242204463923 0 0 0 0 0 0 + -6.954028509809101 2.489845061869568 -10.358996098473584 0 0 0 0 0 + 2.8029986275628964 0.5072464736228206 -0.3988312541770524 -0.04721187230404641 0 0 0 0 + -7.502846399306121 2.561846144803919 -11.627539656261098 -0.18268767659942256 0.030198172008377946 0 0 0 + -7.502846399306121 2.561846144803919 -11.627539656261098 -0.18268767659942256 0.030198172008377946 1 0 0 + -7.502846399306121 2.561846144803919 -11.627539656261098 -0.18268767659942256 0.030198172008377946 1 1 0] + C = T[0 0 0 0 0 0 0 + -14.155112264123755 0 0 0 0 0 0 + -17.97296035885952 -2.859693295451294 0 0 0 0 0 + 147.12150275711716 -1.41221402718213 71.68940251302358 0 0 0 0 + 165.43517024871676 -0.4592823456491126 42.90938336958603 -5.961986721573306 0 0 0 + 24.854864614690072 -3.0009227002832186 47.4931110020768 5.5814197821558125 -0.6610691825249471 0 0 + 30.91273214028599 -3.1208243349937974 77.79954646070892 34.28646028294783 -19.097331116725623 -28.087943162872662 0 + 37.80277123390563 -3.2571969029072276 112.26918849496327 66.9347231244047 -40.06618937091002 -54.66780262877968 -9.48861652309627] + c = T2[0, 0.6358126895828704, 0.4095798393397535, + 0.9769306725060716, 0.4288403609558664, 1, 1, 1] + d = T[0.21193756319429014, -0.42387512638858027, -0.3384627126235924, + 1.8046452872882734, 2.325825639765069, 0, 0, 0] + H = T[25.948786856663858 -2.5579724845846235 10.433815404888879 -2.3679251022685204 0.524948541321073 1.1241088310450404 0.4272876194431874 -0.17202221070155493 + -9.91568850695171 -0.9689944594115154 3.0438037242978453 -24.495224566215796 20.176138334709044 15.98066361424651 -6.789040303419874 -6.710236069923372 + 11.419903575922262 2.8879645146136994 72.92137995996029 80.12511834622643 -52.072871366152654 -59.78993625266729 -0.15582684282751913 4.883087185713722] RodasTableau(A, C, gamma, c, d, H) end diff --git a/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl b/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl index d3967b40ee..c7987db872 100644 --- a/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl +++ b/lib/OrdinaryDiffEqRosenbrock/src/stiff_addsteps.jl @@ -74,7 +74,7 @@ function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::RosenbrockCombinedConst W = 1 / dtgamma - J end - num_stages = size(A,1) + num_stages = size(A, 1) du = f(u, p, t) linsolve_tmp = @.. du + dtd[1] * dT k1 = _reshape(W \ _vec(linsolve_tmp), axes(uprev)) @@ -172,7 +172,6 @@ function _ode_addsteps!(k, t, uprev, u, dt, f, p, cache::RosenbrockCache, @.. $(_vec(ks[stage])) = -linres.u end - for j in 1:size(H, 1) copyat_or_push!(k, j, zero(du)) # Last stage doesn't affect ks diff --git a/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl b/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl index d384937120..7b95c25071 100644 --- a/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl +++ b/lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEqRosenbrock, DiffEqDevTools, Test, LinearAlgebra, LinearSolve +using OrdinaryDiffEqRosenbrock, DiffEqDevTools, Test, LinearAlgebra, LinearSolve, ADTypes import ODEProblemLibrary: prob_ode_linear, prob_ode_2Dlinear, prob_ode_bigfloatlinear, prob_ode_bigfloat2Dlinear @@ -510,11 +510,12 @@ import LinearSolve sol = solve(prob, Rodas4()) @test length(sol) < 20 - sim = test_convergence(dts, prob, Rodas4(autodiff = false), dense_errors = true) + sim = test_convergence( + dts, prob, Rodas4(autodiff = AutoFiniteDiff()), dense_errors = true) @test sim.𝒪est[:final]≈4 atol=testTol @test sim.𝒪est[:L2]≈4 atol=testTol - sol = solve(prob, Rodas4(autodiff = false)) + sol = solve(prob, Rodas4(autodiff = AutoFiniteDiff())) @test length(sol) < 20 sim = test_convergence(dts, prob, Rodas42(), dense_errors = true) @@ -549,29 +550,30 @@ import LinearSolve println("Rodas4 with finite diff") - sim = test_convergence(dts, prob, Rodas4(autodiff = false), dense_errors = true) + sim = test_convergence( + dts, prob, Rodas4(autodiff = AutoFiniteDiff()), dense_errors = true) @test sim.𝒪est[:final]≈4 atol=testTol @test sim.𝒪est[:L2]≈4 atol=testTol - sol = solve(prob, Rodas4(autodiff = false)) + sol = solve(prob, Rodas4(autodiff = AutoFiniteDiff())) @test length(sol) < 20 - sim = test_convergence(dts, prob, Rodas4(autodiff = false, - diff_type = Val{:forward}), + sim = test_convergence( + dts, prob, Rodas4(autodiff = AutoFiniteDiff(fdtype = 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})) + sol = solve(prob, Rodas4(autodiff = AutoFiniteDiff(fdtype = Val(:forward)))) @test length(sol) < 20 - sim = test_convergence(dts, prob, Rodas4(autodiff = false, - diff_type = Val{:complex}), + sim = test_convergence( + dts, prob, Rodas4(autodiff = AutoFiniteDiff(fdtype = 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})) + sol = solve(prob, Rodas4(autodiff = AutoFiniteDiff(fdtype = Val(:forward)))) @test length(sol) < 20 sim = test_convergence(dts, prob, Rodas42(), dense_errors = true) @@ -597,11 +599,12 @@ import LinearSolve println("Rodas4P2 with finite diff") - sim = test_convergence(dts, prob, Rodas4P2(autodiff = false), dense_errors = true) + sim = test_convergence( + dts, prob, Rodas4P2(autodiff = AutoFiniteDiff()), dense_errors = true) @test sim.𝒪est[:final]≈4 atol=testTol @test sim.𝒪est[:L2]≈4 atol=testTol - sol = solve(prob, Rodas4P2(autodiff = false)) + sol = solve(prob, Rodas4P2(autodiff = AutoFiniteDiff())) @test length(sol) < 20 ### Rodas5 @@ -687,7 +690,7 @@ import LinearSolve @test length(sol) < 20 prob = ODEProblem((u, p, t) -> 0.9u, 0.1, (0.0, 1.0)) - @test_nowarn solve(prob, Rosenbrock23(autodiff = false)) + @test_nowarn solve(prob, Rosenbrock23(autodiff = AutoFiniteDiff())) end @testset "Convergence with time-dependent matrix-free Jacobian" begin diff --git a/lib/OrdinaryDiffEqSDIRK/Project.toml b/lib/OrdinaryDiffEqSDIRK/Project.toml index 6204b7309e..46947d958b 100644 --- a/lib/OrdinaryDiffEqSDIRK/Project.toml +++ b/lib/OrdinaryDiffEqSDIRK/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqSDIRK" uuid = "2d112036-d095-4a1e-ab9a-08536f3ecdbf" authors = ["ParamThakkar123 "] -version = "1.1.0" +version = "1.2.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" @@ -18,14 +19,15 @@ SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" TruncatedStacktraces = "781d530d-4396-4725-bb49-402e4bee1e77" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" LinearAlgebra = "<0.0.1, 1" MacroTools = "0.5.13" MuladdMacro = "0.2.4" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.14" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" OrdinaryDiffEqNonlinearSolve = "<0.0.1, 1" Random = "<0.0.1, 1" RecursiveArrayTools = "3.27.0" diff --git a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl index f9fc3bbd9e..f69aefe945 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/OrdinaryDiffEqSDIRK.jl @@ -13,7 +13,8 @@ import OrdinaryDiffEqCore: alg_order, calculate_residuals!, constvalue, _unwrap_val, _ode_interpolant, trivial_limiter!, _ode_interpolant!, isesdirk, issplit, - ssp_coefficient, get_fsalfirstlast, generic_solver_docstring + ssp_coefficient, get_fsalfirstlast, generic_solver_docstring, + _bool_to_ADType, _process_AD_choice using TruncatedStacktraces, MuladdMacro, MacroTools, FastBroadcast, RecursiveArrayTools using SciMLBase: SplitFunction using LinearAlgebra: mul!, I @@ -23,6 +24,7 @@ using OrdinaryDiffEqDifferentiation: UJacobianWrapper, dolinsolve using OrdinaryDiffEqNonlinearSolve: du_alias_or_new, markfirststage!, build_nlsolver, nlsolve!, nlsolvefail, isnewton, get_W, set_new_W!, NLNewton, COEFFICIENT_MULTISTEP +import ADTypes: AutoForwardDiff using Reexport @reexport using DiffEqBase diff --git a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl index 226f92e57f..6ae774eb9c 100644 --- a/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqSDIRK/src/algorithms.jl @@ -5,22 +5,24 @@ function SDIRK_docstring(description::String, extra_keyword_default::String = "") keyword_default = """ chunk_size = Val{0}(), - autodiff = true, + autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), """ * extra_keyword_default keyword_default_description = """ - - `chunk_size`: The chunk size used with ForwardDiff.jl. Defaults to `Val{0}()` - and thus uses the internal ForwardDiff.jl algorithm for the choice. - - `autodiff`: Specifies whether to use automatic differentiation via + - `autodiff`: Uses [ADTypes.jl](https://sciml.github.io/ADTypes.jl/stable/) + to specify whether to use automatic differentiation via [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) or finite - differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). - Defaults to `Val{true}()` for automatic differentiation. + differencing via [FiniteDiff.jl](https://github.com/JuliaDiff/FiniteDiff.jl). + Defaults to `AutoForwardDiff()` for automatic differentiation, which by default uses + `chunksize = 0`, and thus uses the internal ForwardDiff.jl algorithm for the choice. + To use `FiniteDiff.jl`, the `AutoFiniteDiff()` ADType can be used, which has a keyword argument + `fdtype` with default value `Val{:forward}()`, and alternatives `Val{:central}()` and `Val{:complex}()`. - `standardtag`: Specifies whether to use package-specific tags instead of the ForwardDiff default function-specific tags. For more information, see [this blog post](https://www.stochasticlifestyle.com/improved-forwarddiff-jl-stacktraces-with-package-tags/). @@ -28,9 +30,6 @@ function SDIRK_docstring(description::String, - `concrete_jac`: Specifies whether a Jacobian should be constructed. Defaults to `nothing`, which means it will be chosen true/false depending on circumstances of the solver, such as whether a Krylov subspace method is used for `linsolve`. - - `diff_type`: The type of differentiation used in FiniteDiff.jl if `autodiff=false`. - Defaults to `Val{:forward}`, with alternatives of `Val{:central}` and - `Val{:complex}`. - `linsolve`: Any [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl) compatible linear solver. For example, to use [KLU.jl](https://github.com/JuliaSparse/KLU.jl), specify `$name(linsolve = KLUFactorization()`). @@ -106,18 +105,21 @@ struct ImplicitEuler{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function ImplicitEuler(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ImplicitEuler(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + ImplicitEuler{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + nlsolve, precs, extrapolant, controller, step_limiter!, AD_choice) end @doc SDIRK_docstring("A second order A-stable symplectic and symmetric implicit solver. @@ -144,20 +146,23 @@ struct ImplicitMidpoint{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: precs::P extrapolant::Symbol step_limiter!::StepLimiter + autodiff::AD end -function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ImplicitMidpoint(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + ImplicitMidpoint{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(step_limiter!)}(linsolve, nlsolve, precs, extrapolant, - step_limiter!) + step_limiter!, AD_choice) end @doc SDIRK_docstring( @@ -186,22 +191,26 @@ struct Trapezoid{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function Trapezoid(; chunk_size = Val{0}(), autodiff = Val{true}(), +function Trapezoid(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + Trapezoid{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + step_limiter!, + AD_choice) end @doc SDIRK_docstring("A second order A-B-L-S-stable one-step ESDIRK method. @@ -238,17 +247,21 @@ struct TRBDF2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function TRBDF2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function TRBDF2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + TRBDF2{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end TruncatedStacktraces.@truncate_stacktrace TRBDF2 @@ -285,19 +298,24 @@ struct SDIRK2{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function SDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function SDIRK2(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SDIRK2{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + step_limiter!, + AD_choice) end @doc SDIRK_docstring("Description TBD", @@ -326,22 +344,26 @@ struct SDIRK22{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end function SDIRK22(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + Trapezoid{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + step_limiter!, + AD_choice) end @doc SDIRK_docstring( @@ -378,18 +400,21 @@ struct SSPSDIRK2{CS, AD, F, F2, P, FDT, ST, CJ} <: smooth_est::Bool extrapolant::Symbol controller::Symbol + autodiff::AD end -function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = Val{true}(), +function SSPSDIRK2(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SSPSDIRK2{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring("An A-L stable stiffly-accurate 3rd order ESDIRK method.", @@ -424,17 +449,20 @@ struct Kvaerno3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function Kvaerno3(; chunk_size = Val{0}(), autodiff = Val{true}(), +function Kvaerno3(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + Kvaerno3{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end @doc SDIRK_docstring( @@ -466,17 +494,20 @@ struct KenCarp3{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function KenCarp3(; chunk_size = Val{0}(), autodiff = Val{true}(), +function KenCarp3(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + KenCarp3{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end @doc SDIRK_docstring("Third order method.", @@ -502,18 +533,22 @@ struct CFNLIRK3{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function CFNLIRK3(; chunk_size = Val{0}(), autodiff = Val{true}(), +function CFNLIRK3(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) - CFNLIRK3{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + CFNLIRK3{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc SDIRK_docstring("An A-L stable 4th order SDIRK method.", @@ -548,14 +583,18 @@ struct Cash4{CS, AD, F, F2, P, FDT, ST, CJ} <: extrapolant::Symbol embedding::Int controller::Symbol + autodiff::AD end -function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function Cash4(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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) + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + Cash4{ - _unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + _unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}( linsolve, nlsolve, @@ -563,7 +602,8 @@ function Cash4(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Va smooth_est, extrapolant, embedding, - controller) + controller, + AD_choice) end @doc SDIRK_docstring("Method of order 4.", @@ -589,18 +629,22 @@ struct SFSDIRK4{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function SFSDIRK4(; chunk_size = Val{0}(), autodiff = Val{true}(), +function SFSDIRK4(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) - SFSDIRK4{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SFSDIRK4{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc SDIRK_docstring("Method of order 5.", @@ -626,19 +670,23 @@ struct SFSDIRK5{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function SFSDIRK5(; chunk_size = Val{0}(), autodiff = Val{true}(), +function SFSDIRK5(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) - SFSDIRK5{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SFSDIRK5{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc SDIRK_docstring("Method of order 6.", @@ -664,19 +712,23 @@ struct SFSDIRK6{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function SFSDIRK6(; chunk_size = Val{0}(), autodiff = Val{true}(), +function SFSDIRK6(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) - SFSDIRK6{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SFSDIRK6{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc SDIRK_docstring("Method of order 7.", @@ -702,19 +754,23 @@ struct SFSDIRK7{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function SFSDIRK7(; chunk_size = Val{0}(), autodiff = Val{true}(), +function SFSDIRK7(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) - SFSDIRK7{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SFSDIRK7{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc SDIRK_docstring("Method of order 8.", @@ -740,19 +796,23 @@ struct SFSDIRK8{CS, AD, F, F2, P, FDT, ST, CJ} <: nlsolve::F2 precs::P extrapolant::Symbol + autodiff::AD end -function SFSDIRK8(; chunk_size = Val{0}(), autodiff = Val{true}(), +function SFSDIRK8(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), extrapolant = :linear) - SFSDIRK8{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + SFSDIRK8{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, - extrapolant) + extrapolant, + AD_choice) end @doc SDIRK_docstring("An A-L stable 4th order SDIRK method.", @@ -778,17 +838,20 @@ struct Hairer4{CS, AD, F, F2, P, FDT, ST, CJ} <: smooth_est::Bool extrapolant::Symbol controller::Symbol + autodiff::AD end function Hairer4(; - chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + Hairer4{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring("An A-L stable 4th order SDIRK method.", @@ -814,17 +877,20 @@ struct Hairer42{CS, AD, F, F2, P, FDT, ST, CJ} <: smooth_est::Bool extrapolant::Symbol controller::Symbol + autodiff::AD end -function Hairer42(; chunk_size = Val{0}(), autodiff = Val{true}(), +function Hairer42(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + Hairer42{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring("An A-L stable stiffly-accurate 4th order ESDIRK method.", @@ -859,17 +925,20 @@ struct Kvaerno4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function Kvaerno4(; chunk_size = Val{0}(), autodiff = Val{true}(), +function Kvaerno4(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + Kvaerno4{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end @doc SDIRK_docstring("An A-L stable stiffly-accurate 5th order ESDIRK method.", @@ -904,17 +973,20 @@ struct Kvaerno5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function Kvaerno5(; chunk_size = Val{0}(), autodiff = Val{true}(), +function Kvaerno5(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + Kvaerno5{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end @doc SDIRK_docstring( @@ -946,17 +1018,20 @@ struct KenCarp4{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function KenCarp4(; chunk_size = Val{0}(), autodiff = Val{true}(), +function KenCarp4(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + KenCarp4{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end TruncatedStacktraces.@truncate_stacktrace KenCarp4 @@ -990,17 +1065,20 @@ struct KenCarp47{CS, AD, F, F2, P, FDT, ST, CJ} <: smooth_est::Bool extrapolant::Symbol controller::Symbol + autodiff::AD end -function KenCarp47(; chunk_size = Val{0}(), autodiff = Val{true}(), +function KenCarp47(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + KenCarp47{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring( @@ -1032,17 +1110,20 @@ struct KenCarp5{CS, AD, F, F2, P, FDT, ST, CJ, StepLimiter} <: extrapolant::Symbol controller::Symbol step_limiter!::StepLimiter + autodiff::AD end -function KenCarp5(; chunk_size = Val{0}(), autodiff = Val{true}(), +function KenCarp5(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + KenCarp5{_unwrap_val(chunk_size), typeof(AD_choice), 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!) + smooth_est, extrapolant, controller, step_limiter!, AD_choice) end @doc SDIRK_docstring( @@ -1074,17 +1155,20 @@ struct KenCarp58{CS, AD, F, F2, P, FDT, ST, CJ} <: smooth_est::Bool extrapolant::Symbol controller::Symbol + autodiff::AD end -function KenCarp58(; chunk_size = Val{0}(), autodiff = Val{true}(), +function KenCarp58(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + KenCarp58{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, smooth_est, extrapolant, - controller) + controller, AD_choice) end # `smooth_est` is not necessary, as the embedded method is also L-stable @@ -1116,16 +1200,19 @@ struct ESDIRK54I8L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: precs::P extrapolant::Symbol controller::Symbol + autodiff::AD end -function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ESDIRK54I8L2SA(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + ESDIRK54I8L2SA{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring( @@ -1156,16 +1243,19 @@ struct ESDIRK436L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: precs::P extrapolant::Symbol controller::Symbol + autodiff::AD end -function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ESDIRK436L2SA2(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + ESDIRK436L2SA2{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring( @@ -1197,15 +1287,17 @@ struct ESDIRK437L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: extrapolant::Symbol controller::Symbol end -function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ESDIRK437L2SA(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + ESDIRK437L2SA{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring( @@ -1236,16 +1328,19 @@ struct ESDIRK547L2SA2{CS, AD, F, F2, P, FDT, ST, CJ} <: precs::P extrapolant::Symbol controller::Symbol + autodiff::AD end -function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ESDIRK547L2SA2(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + ESDIRK547L2SA2{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) + controller, AD_choice) end @doc SDIRK_docstring( @@ -1278,14 +1373,17 @@ struct ESDIRK659L2SA{CS, AD, F, F2, P, FDT, ST, CJ} <: precs::P extrapolant::Symbol controller::Symbol + autodiff::AD end -function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = Val{true}(), +function ESDIRK659L2SA(; chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), concrete_jac = nothing, - diff_type = Val{:forward}, + 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), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + ESDIRK659L2SA{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac)}(linsolve, nlsolve, precs, extrapolant, - controller) + controller, AD_choice) end diff --git a/lib/OrdinaryDiffEqSDIRK/test/sdirk_convergence_tests.jl b/lib/OrdinaryDiffEqSDIRK/test/sdirk_convergence_tests.jl index 4e9cd86216..884e8bc7f3 100644 --- a/lib/OrdinaryDiffEqSDIRK/test/sdirk_convergence_tests.jl +++ b/lib/OrdinaryDiffEqSDIRK/test/sdirk_convergence_tests.jl @@ -1,5 +1,5 @@ # This definitely needs cleaning -using OrdinaryDiffEqSDIRK, ODEProblemLibrary, DiffEqDevTools +using OrdinaryDiffEqSDIRK, ODEProblemLibrary, DiffEqDevTools, ADTypes using Test, Random Random.seed!(100) @@ -56,7 +56,7 @@ testTol = 0.2 sim14 = test_convergence(dts, prob, TRBDF2()) @test sim14.𝒪est[:final]≈2 atol=testTol - sim152 = test_convergence(dts, prob, TRBDF2(autodiff = false)) + sim152 = test_convergence(dts, prob, TRBDF2(autodiff = AutoFiniteDiff())) @test sim152.𝒪est[:final]≈2 atol=testTol + 0.1 sim15 = test_convergence(dts, prob, SDIRK2()) diff --git a/lib/OrdinaryDiffEqSSPRK/test/ode_ssprk_tests.jl b/lib/OrdinaryDiffEqSSPRK/test/ode_ssprk_tests.jl index ec0c73f11b..444ec1b7d5 100644 --- a/lib/OrdinaryDiffEqSSPRK/test/ode_ssprk_tests.jl +++ b/lib/OrdinaryDiffEqSSPRK/test/ode_ssprk_tests.jl @@ -80,7 +80,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 println("KYKSSPRK42") @@ -134,7 +134,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 println("SSPRK53") @@ -160,7 +160,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 println("SSPRK53_2N1") @@ -186,7 +186,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 # for SSPRK53_2N2 to be in asymptotic range @@ -214,7 +214,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 3 dts = 1 .// 2 .^ (9:-1:5) @@ -241,7 +241,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 4 #reverting back to original dts @@ -334,7 +334,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 println("SSPRK432") @@ -368,7 +368,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 alg = SSPRKMSVS32() @@ -423,7 +423,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 println("SSPRK54") @@ -470,7 +470,7 @@ integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = fal save_everystep = false) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 6 integ = init(prob_ode_large, alg, dt = 1.e-2, save_start = false, save_end = false, - save_everystep = false, alias_u0 = true) + save_everystep = false, alias = ODEAliasSpecifier(alias_u0 = true)) @test Base.summarysize(integ) ÷ Base.summarysize(u0_large) <= 5 println("KYK2014DGSSPRK_3S2") diff --git a/lib/OrdinaryDiffEqStabilizedIRK/Project.toml b/lib/OrdinaryDiffEqStabilizedIRK/Project.toml index da92cbbb91..660cbb9961 100644 --- a/lib/OrdinaryDiffEqStabilizedIRK/Project.toml +++ b/lib/OrdinaryDiffEqStabilizedIRK/Project.toml @@ -1,9 +1,10 @@ name = "OrdinaryDiffEqStabilizedIRK" uuid = "e3e12d00-db14-5390-b879-ac3dd2ef6296" authors = ["ParamThakkar123 "] -version = "1.1.0" +version = "1.2.0" [deps] +ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" @@ -15,13 +16,14 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] +ADTypes = "1.11" DiffEqBase = "6.152.2" DiffEqDevTools = "2.44.4" FastBroadcast = "0.3.5" LinearAlgebra = "<0.0.1, 1" MuladdMacro = "0.2.4" -OrdinaryDiffEqCore = "1.1" -OrdinaryDiffEqDifferentiation = "<0.0.1, 1" +OrdinaryDiffEqCore = "1.14" +OrdinaryDiffEqDifferentiation = "<0.0.1, 1.2" OrdinaryDiffEqNonlinearSolve = "<0.0.1, 1" Random = "<0.0.1, 1" RecursiveArrayTools = "3.27.0" diff --git a/lib/OrdinaryDiffEqStabilizedIRK/src/OrdinaryDiffEqStabilizedIRK.jl b/lib/OrdinaryDiffEqStabilizedIRK/src/OrdinaryDiffEqStabilizedIRK.jl index f16310de7e..b2e154c6f4 100644 --- a/lib/OrdinaryDiffEqStabilizedIRK/src/OrdinaryDiffEqStabilizedIRK.jl +++ b/lib/OrdinaryDiffEqStabilizedIRK/src/OrdinaryDiffEqStabilizedIRK.jl @@ -11,7 +11,7 @@ import OrdinaryDiffEqCore: alg_order, alg_maximum_order, OrdinaryDiffEqAdaptiveImplicitAlgorithm, alg_cache, _unwrap_val, DEFAULT_PRECS, @cache, _reshape, _vec, full_cache, get_fsalfirstlast, - generic_solver_docstring + generic_solver_docstring, _bool_to_ADType, _process_AD_choice using OrdinaryDiffEqDifferentiation: dolinsolve, update_W! using OrdinaryDiffEqNonlinearSolve: NLNewton, nlsolve!, isnewton, build_nlsolver, @@ -19,6 +19,7 @@ using OrdinaryDiffEqNonlinearSolve: NLNewton, nlsolve!, isnewton, build_nlsolver using FastBroadcast, MuladdMacro, RecursiveArrayTools import StaticArrays: SArray, MVector, SVector, @SVector, StaticArray, MMatrix, SA import OrdinaryDiffEqCore +import ADTypes: AutoForwardDiff, AbstractADType using Reexport @reexport using DiffEqBase diff --git a/lib/OrdinaryDiffEqStabilizedIRK/src/algorithms.jl b/lib/OrdinaryDiffEqStabilizedIRK/src/algorithms.jl index 78cb42bc88..0d9106a18e 100644 --- a/lib/OrdinaryDiffEqStabilizedIRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqStabilizedIRK/src/algorithms.jl @@ -17,15 +17,19 @@ struct IRKC{CS, AD, F, F2, P, FDT, ST, CJ, K, T, E} <: extrapolant::Symbol controller::Symbol eigen_est::E + autodiff::AD end -function IRKC(; chunk_size = Val{0}(), autodiff = Val{true}(), standardtag = Val{true}(), - concrete_jac = nothing, diff_type = Val{:forward}, +function IRKC(; + chunk_size = Val{0}(), autodiff = AutoForwardDiff(), standardtag = Val{true}(), + concrete_jac = nothing, diff_type = Val{:forward}(), linsolve = nothing, precs = DEFAULT_PRECS, nlsolve = NLNewton(), κ = nothing, tol = nothing, extrapolant = :linear, controller = :Standard, eigen_est = nothing) - IRKC{_unwrap_val(chunk_size), _unwrap_val(autodiff), typeof(linsolve), typeof(nlsolve), + AD_choice = _process_AD_choice(autodiff, chunk_size, diff_type) + + IRKC{_unwrap_val(chunk_size), typeof(AD_choice), typeof(linsolve), typeof(nlsolve), typeof(precs), diff_type, _unwrap_val(standardtag), _unwrap_val(concrete_jac), typeof(κ), typeof(tol), typeof(eigen_est)}(linsolve, nlsolve, precs, κ, tol, - extrapolant, controller, eigen_est) + extrapolant, controller, eigen_est, AD_choice) end diff --git a/lib/OrdinaryDiffEqSymplecticRK/Project.toml b/lib/OrdinaryDiffEqSymplecticRK/Project.toml index 9c32d09c76..a7d31a18ec 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/Project.toml +++ b/lib/OrdinaryDiffEqSymplecticRK/Project.toml @@ -1,7 +1,7 @@ name = "OrdinaryDiffEqSymplecticRK" uuid = "fa646aed-7ef9-47eb-84c4-9443fc8cbfa8" authors = ["ParamThakkar123 "] -version = "1.1.0" +version = "1.2.0" [deps] DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" @@ -26,7 +26,7 @@ Random = "<0.0.1, 1" RecursiveArrayTools = "3.27.0" Reexport = "1.2.2" SafeTestsets = "0.1.0" -Statistics = "1.11.1" +Statistics = "<0.0.1, 1" Test = "<0.0.1, 1" julia = "1.10" diff --git a/lib/OrdinaryDiffEqSymplecticRK/src/OrdinaryDiffEqSymplecticRK.jl b/lib/OrdinaryDiffEqSymplecticRK/src/OrdinaryDiffEqSymplecticRK.jl index c100a75215..f3700520ea 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/src/OrdinaryDiffEqSymplecticRK.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/src/OrdinaryDiffEqSymplecticRK.jl @@ -25,8 +25,8 @@ include("symplectic_caches.jl") include("symplectic_tableaus.jl") include("symplectic_perform_step.jl") -export SymplecticEuler, VelocityVerlet, VerletLeapfrog, PseudoVerletLeapfrog, - McAte2, Ruth3, McAte3, CandyRoz4, McAte4, McAte42, McAte5, +export SymplecticEuler, VelocityVerlet, VerletLeapfrog, LeapfrogDriftKickDrift, + PseudoVerletLeapfrog, McAte2, Ruth3, McAte3, CandyRoz4, McAte4, McAte42, McAte5, CalvoSanz4, Yoshida6, KahanLi6, McAte8, KahanLi8, SofSpa10 end diff --git a/lib/OrdinaryDiffEqSymplecticRK/src/alg_utils.jl b/lib/OrdinaryDiffEqSymplecticRK/src/alg_utils.jl index e6d418bb8a..e39a4d34f0 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/src/alg_utils.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/src/alg_utils.jl @@ -1,6 +1,7 @@ alg_order(alg::SymplecticEuler) = 1 alg_order(alg::VelocityVerlet) = 2 alg_order(alg::VerletLeapfrog) = 2 +alg_order(alg::LeapfrogDriftKickDrift) = 2 alg_order(alg::PseudoVerletLeapfrog) = 2 alg_order(alg::McAte2) = 2 alg_order(alg::Ruth3) = 3 diff --git a/lib/OrdinaryDiffEqSymplecticRK/src/algorithms.jl b/lib/OrdinaryDiffEqSymplecticRK/src/algorithms.jl index cdbc53d2e1..3d4965ac98 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/src/algorithms.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/src/algorithms.jl @@ -24,12 +24,38 @@ publisher={APS} verlet1967, "", "") struct VelocityVerlet <: OrdinaryDiffEqPartitionedAlgorithm end -@doc generic_solver_docstring("2nd order explicit symplectic integrator.", +monaghan2005 = """ +@article{monaghan2005, + title = {Smoothed particle hydrodynamics}, + author = {Monaghan, Joseph J.}, + year = {2005}, + journal = {Reports on Progress in Physics}, + volume = {68}, + number = {8}, + pages = {1703--1759}, + doi = {10.1088/0034-4885/68/8/R01}, +} +""" + +@doc generic_solver_docstring( + "2nd order explicit symplectic integrator. Kick-drift-kick form. Requires only one evaluation of `f1` per step.", "VerletLeapfrog", "Symplectic Runge-Kutta Methods", - verlet1967, "", "") + monaghan2005, "", "") struct VerletLeapfrog <: OrdinaryDiffEqPartitionedAlgorithm end +OrdinaryDiffEqCore.default_linear_interpolation(alg::VerletLeapfrog, prob) = true + +@doc generic_solver_docstring( + "2nd order explicit symplectic integrator. Drift-kick-drift form of `VerletLeapfrog` +designed to work when `f1` depends on `v`. Requires two evaluation of `f1` per step.", + "LeapfrogDriftKickDrift", + "Symplectic Runge-Kutta Methods", + monaghan2005, "", "") +struct LeapfrogDriftKickDrift <: OrdinaryDiffEqPartitionedAlgorithm end + +OrdinaryDiffEqCore.default_linear_interpolation(alg::LeapfrogDriftKickDrift, prob) = true + @doc generic_solver_docstring("2nd order explicit symplectic integrator.", "PseudoVerletLeapfrog", "Symplectic Runge-Kutta Methods", diff --git a/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_caches.jl b/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_caches.jl index dca14b6d28..e9b0ca838c 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_caches.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_caches.jl @@ -57,13 +57,50 @@ function alg_cache(alg::VelocityVerlet, u, rate_prototype, ::Type{uEltypeNoUnits VelocityVerletConstantCache(uEltypeNoUnits(1 // 2)) end -@cache struct Symplectic2Cache{uType, rateType, tableauType} <: HamiltonMutableCache +@cache struct LeapfrogDriftKickDriftCache{uType, rateType, uEltypeNoUnits} <: + OrdinaryDiffEqMutableCache u::uType uprev::uType tmp::uType k::rateType fsalfirst::rateType - tab::tableauType + half::uEltypeNoUnits +end + +struct LeapfrogDriftKickDriftConstantCache{uEltypeNoUnits} <: HamiltonConstantCache + half::uEltypeNoUnits +end + +function alg_cache(alg::LeapfrogDriftKickDrift, 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(rate_prototype) + k = zero(rate_prototype) + fsalfirst = zero(rate_prototype) + half = uEltypeNoUnits(1 // 2) + LeapfrogDriftKickDriftCache(u, uprev, k, tmp, fsalfirst, half) +end + +function alg_cache(alg::LeapfrogDriftKickDrift, u, rate_prototype, ::Type{uEltypeNoUnits}, + ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, + dt, reltol, p, calck, + ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} + LeapfrogDriftKickDriftConstantCache(uEltypeNoUnits(1 // 2)) +end + +@cache struct VerletLeapfrogCache{uType, rateType, uEltypeNoUnits} <: + OrdinaryDiffEqMutableCache + u::uType + uprev::uType + tmp::uType + k::rateType + fsalfirst::rateType + half::uEltypeNoUnits +end + +struct VerletLeapfrogConstantCache{uEltypeNoUnits} <: HamiltonConstantCache + half::uEltypeNoUnits end function alg_cache(alg::VerletLeapfrog, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -73,16 +110,24 @@ function alg_cache(alg::VerletLeapfrog, u, rate_prototype, ::Type{uEltypeNoUnits tmp = zero(u) k = zero(rate_prototype) fsalfirst = zero(rate_prototype) - tab = VerletLeapfrogConstantCache(constvalue(uBottomEltypeNoUnits), - constvalue(tTypeNoUnits)) - Symplectic2Cache(u, uprev, k, tmp, fsalfirst, tab) + half = uEltypeNoUnits(1 // 2) + VerletLeapfrogCache(u, uprev, k, tmp, fsalfirst, half) end function alg_cache(alg::VerletLeapfrog, u, rate_prototype, ::Type{uEltypeNoUnits}, ::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t, dt, reltol, p, calck, ::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits} - VerletLeapfrogConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits)) + VerletLeapfrogConstantCache(uEltypeNoUnits(1 // 2)) +end + +@cache struct Symplectic2Cache{uType, rateType, tableauType} <: HamiltonMutableCache + u::uType + uprev::uType + tmp::uType + k::rateType + fsalfirst::rateType + tab::tableauType end function alg_cache(alg::PseudoVerletLeapfrog, u, rate_prototype, ::Type{uEltypeNoUnits}, @@ -422,6 +467,7 @@ function alg_cache(alg::SofSpa10, u, rate_prototype, ::Type{uEltypeNoUnits}, end function get_fsalfirstlast( - cache::Union{HamiltonMutableCache, VelocityVerletCache, SymplecticEulerCache}, u) + cache::Union{HamiltonMutableCache, VelocityVerletCache, VerletLeapfrogCache, + SymplecticEulerCache, LeapfrogDriftKickDriftCache}, u) (cache.fsalfirst, cache.k) end diff --git a/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_perform_step.jl b/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_perform_step.jl index 2e581be283..fcbf00b2f1 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_perform_step.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_perform_step.jl @@ -77,8 +77,14 @@ end # f.f2(p, q, pa, t) = p which is the Newton/Lagrange equations # If called with different functions (which are possible in the Hamiltonian case) # an exception is thrown to avoid silently calculate wrong results. -verify_f2(f, p, q, pa, t, ::Any, ::C) where {C <: HamiltonConstantCache} = f(p, q, pa, t) -function verify_f2(f, res, p, q, pa, t, ::Any, ::C) where {C <: HamiltonMutableCache} +function verify_f2(f, p, q, pa, t, ::Any, + ::C) where {C <: Union{HamiltonConstantCache, VerletLeapfrogConstantCache, + LeapfrogDriftKickDriftConstantCache}} + f(p, q, pa, t) +end +function verify_f2(f, res, p, q, pa, t, ::Any, + ::C) where {C <: Union{HamiltonMutableCache, VerletLeapfrogCache, + LeapfrogDriftKickDriftCache}} f(res, p, q, pa, t) end @@ -124,8 +130,8 @@ function store_symp_state!(integrator, ::OrdinaryDiffEqMutableCache, kdu, ku) end function initialize!(integrator, - cache::C) where {C <: - Union{HamiltonMutableCache, VelocityVerletCache}} + cache::C) where {C <: Union{HamiltonMutableCache, VelocityVerletCache, + VerletLeapfrogCache, LeapfrogDriftKickDriftCache}} integrator.kshortsize = 2 resize!(integrator.k, integrator.kshortsize) integrator.k[1] = integrator.fsalfirst @@ -140,9 +146,8 @@ function initialize!(integrator, end function initialize!(integrator, - cache::C) where { - C <: - Union{HamiltonConstantCache, VelocityVerletConstantCache}} + cache::C) where {C <: Union{HamiltonConstantCache, VelocityVerletConstantCache, + VerletLeapfrogConstantCache, LeapfrogDriftKickDriftConstantCache}} integrator.kshortsize = 2 integrator.k = typeof(integrator.k)(undef, integrator.kshortsize) @@ -171,7 +176,7 @@ end # v(t+Δt) = v(t) + 1/2*(a(t)+a(t+Δt))*Δt du = duprev + dt * (half * ku + half * kdu) - OrdinaryDiffEqCore.increment_nf!(integrator.stats, 2) + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) store_symp_state!(integrator, cache, du, u, kdu, du) end @@ -186,13 +191,118 @@ end half = cache.half @.. broadcast=false u=uprev + dt * duprev + dtsq * (half * ku) f.f1(kdu, duprev, u, p, t + dt) - OrdinaryDiffEqCore.increment_nf!(integrator.stats, 2) + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) # v(t+Δt) = v(t) + 1/2*(a(t)+a(t+Δt))*Δt @.. broadcast=false du=duprev + dt * (half * ku + half * kdu) store_symp_state!(integrator, cache, kdu, du) end +@muladd function perform_step!(integrator, cache::VerletLeapfrogConstantCache, + repeat_step = false) + @unpack t, dt, f, p = integrator + duprev, uprev, kduprev, _ = load_symp_state(integrator) + + # kick-drift-kick scheme of the Leapfrog method: + # update velocity + half = cache.half + du = duprev + dt * half * kduprev + + # update position + ku = f.f2(du, uprev, p, t + half * dt) + u = uprev + dt * ku + + # update velocity + kdu = f.f1(du, u, p, t + dt) + du = du + dt * half * kdu + + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) + integrator.stats.nf2 += 1 + store_symp_state!(integrator, cache, du, u, kdu, ku) +end + +@muladd function perform_step!(integrator, cache::VerletLeapfrogCache, repeat_step = false) + @unpack t, dt, f, p = integrator + duprev, uprev, kduprev, _ = load_symp_state(integrator) + du, u, kdu, ku = alloc_symp_state(integrator) + + # kick-drift-kick scheme of the Leapfrog method: + # update velocity + half = cache.half + @.. broadcast=false du=duprev + dt * half * kduprev + + # update position + f.f2(ku, du, uprev, p, t + half * dt) + @.. broadcast=false u=uprev + dt * ku + + # update velocity + f.f1(kdu, du, u, p, t + dt) + @.. broadcast=false du=du + dt * half * kdu + + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 1) + integrator.stats.nf2 += 1 + store_symp_state!(integrator, cache, kdu, ku) +end + +@muladd function perform_step!(integrator, cache::LeapfrogDriftKickDriftConstantCache, + repeat_step = false) + @unpack t, dt, f, p = integrator + duprev, uprev, _, _ = load_symp_state(integrator) + + # drift-kick-drift scheme of the Leapfrog method, allowing for f1 to depend on v: + # update position half step + half = cache.half + ku = f.f2(duprev, uprev, p, t) + u = uprev + dt * half * ku + + # update velocity half step + kdu = f.f1(duprev, uprev, p, t) + du = duprev + dt * half * kdu + + # update velocity (add to previous full step velocity) + # note that this extra step is only necessary if f1 depends on v/du (or t) + kdu = f.f1(du, u, p, t + half * dt) + du = duprev + dt * kdu + + # update position (add to half step position) + ku = f.f2(du, u, p, t + dt) + u = u + dt * half * ku + + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 2) + integrator.stats.nf2 += 2 + store_symp_state!(integrator, cache, du, u, kdu, ku) +end + +@muladd function perform_step!(integrator, cache::LeapfrogDriftKickDriftCache, + repeat_step = false) + @unpack t, dt, f, p = integrator + duprev, uprev, _, _ = load_symp_state(integrator) + du, u, kdu, ku = alloc_symp_state(integrator) + + # drift-kick-drift scheme of the Leapfrog method, allowing for f1 to depend on v: + # update position half step + half = cache.half + f.f2(ku, duprev, uprev, p, t) + @.. broadcast=false u=uprev + dt * half * ku + + # update velocity half step + f.f1(kdu, duprev, uprev, p, t) + @.. broadcast=false du=duprev + dt * half * kdu + + # update velocity (add to previous full step velocity) + # note that this extra step is only necessary if f1 depends on v/du (or t) + f.f1(kdu, du, u, p, t + half * dt) + @.. broadcast=false du=duprev + dt * kdu + + # update position (add to half step position) + f.f2(ku, du, u, p, t + dt) + @.. broadcast=false u=u + dt * half * ku + + OrdinaryDiffEqCore.increment_nf!(integrator.stats, 2) + integrator.stats.nf2 += 2 + store_symp_state!(integrator, cache, kdu, ku) +end + @muladd function perform_step!(integrator, cache::Symplectic2ConstantCache, repeat_step = false) @unpack t, dt, f, p = integrator diff --git a/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_tableaus.jl b/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_tableaus.jl index fd5acd6e61..61e791c57f 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_tableaus.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/src/symplectic_tableaus.jl @@ -21,14 +21,6 @@ function McAte2ConstantCache(T, T2) Symplectic2ConstantCache{T, T2}(a1, a2, b1, b2) end -function VerletLeapfrogConstantCache(T, T2) - a1 = convert(T, 1 // 2) - a2 = convert(T, 1 // 2) - b1 = convert(T, 0) - b2 = convert(T, 1) - Symplectic2ConstantCache{T, T2}(a1, a2, b1, b2) -end - struct Symplectic3ConstantCache{T, T2} <: HamiltonConstantCache a1::T a2::T diff --git a/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_convergence.jl b/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_convergence.jl index 0939c97897..c303ee0799 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_convergence.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_convergence.jl @@ -62,6 +62,9 @@ position_error = :final => [mean(sim[i].u[2].x[1] - sim[i].u_analytic[2].x[1]) sim = test_convergence(dts, prob, VerletLeapfrog(), dense_errors = true) @test sim.𝒪est[:l2]≈2 rtol=1e-1 @test sim.𝒪est[:L2]≈2 rtol=1e-1 +sim = test_convergence(dts, prob, LeapfrogDriftKickDrift(), dense_errors = true) +@test sim.𝒪est[:l2]≈2 rtol=1e-1 +@test sim.𝒪est[:L2]≈2 rtol=1e-1 sim = test_convergence(dts, prob, PseudoVerletLeapfrog(), dense_errors = true) @test sim.𝒪est[:l2]≈2 rtol=1e-1 @test sim.𝒪est[:L2]≈2 rtol=1e-1 @@ -151,6 +154,9 @@ position_error = :final => [mean(sim[i].u[2].x[1] - sim[i].u_analytic[2].x[1]) sim = test_convergence(dts, prob, VerletLeapfrog(), dense_errors = true) @test sim.𝒪est[:l2]≈2 rtol=1e-1 @test sim.𝒪est[:L2]≈2 rtol=1e-1 +sim = test_convergence(dts, prob, LeapfrogDriftKickDrift(), dense_errors = true) +@test sim.𝒪est[:l2]≈2 rtol=1e-1 +@test sim.𝒪est[:L2]≈2 rtol=1e-1 sim = test_convergence(dts, prob, PseudoVerletLeapfrog(), dense_errors = true) @test sim.𝒪est[:l2]≈2 rtol=1e-1 @test sim.𝒪est[:L2]≈2 rtol=1e-1 @@ -202,3 +208,28 @@ dts = 1.0 ./ 2.0 .^ (2:-1:-2) sim = test_convergence(dts, prob, SofSpa10(), dense_errors = true) @test sim.𝒪est[:l2]≈10 rtol=1e-1 @test sim.𝒪est[:L2]≈4 rtol=1e-1 + +################# f1 dependent on v + +println("f1 dependent on v") + +u0 = fill(0.0, 2) +v0 = ones(2) +function f1_v(dv, v, u, p, t) + dv .= v +end +function f2_v(du, v, u, p, t) + du .= v +end +function f_v_analytic(y0, p, x) + v0, u0 = y0.x + ArrayPartition(v0 * exp(x), v0 * exp(x) - v0 + u0) +end +ff_v = DynamicalODEFunction(f1_v, f2_v; analytic = f_v_analytic) +prob = DynamicalODEProblem(ff_v, v0, u0, (0.0, 5.0)) + +dts = 1 .// 2 .^ (6:-1:3) +# LeapfrogDriftKickDrift +sim = test_convergence(dts, prob, LeapfrogDriftKickDrift(), dense_errors = true) +@test sim.𝒪est[:l2]≈2 rtol=1e-1 +@test sim.𝒪est[:L2]≈2 rtol=1e-1 diff --git a/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_tests.jl b/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_tests.jl index e1771678b2..32b2a8f52a 100644 --- a/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_tests.jl +++ b/lib/OrdinaryDiffEqSymplecticRK/test/symplectic_tests.jl @@ -7,6 +7,7 @@ using OrdinaryDiffEqRKN const ALGOS = ((SymplecticEuler, true, 1), (VelocityVerlet, false, 2), (VerletLeapfrog, true, 2), + (LeapfrogDriftKickDrift, true, 2), (PseudoVerletLeapfrog, true, 2), (McAte2, true, 2), (Ruth3, true, 3), diff --git a/src/OrdinaryDiffEq.jl b/src/OrdinaryDiffEq.jl index f6578c3bde..e689440fbf 100644 --- a/src/OrdinaryDiffEq.jl +++ b/src/OrdinaryDiffEq.jl @@ -6,7 +6,8 @@ module OrdinaryDiffEq using Reexport @reexport using DiffEqBase -import OrdinaryDiffEqCore: trivial_limiter!, CompositeAlgorithm, alg_order, +import OrdinaryDiffEqCore: OrdinaryDiffEqCore, + trivial_limiter!, CompositeAlgorithm, alg_order, ShampineCollocationInit, BrownFullBasicInit, NoInit, set_new_W!, set_W_γdt!, get_W, isfirstcall, isfirststage, isJcurrent, get_new_W_γdt_cutoff, @@ -113,8 +114,8 @@ using OrdinaryDiffEqFeagin export Feagin10, Feagin12, Feagin14 using OrdinaryDiffEqSymplecticRK -export SymplecticEuler, VelocityVerlet, VerletLeapfrog, PseudoVerletLeapfrog, - McAte2, Ruth3, McAte3, CandyRoz4, McAte4, McAte42, McAte5, +export SymplecticEuler, VelocityVerlet, VerletLeapfrog, LeapfrogDriftKickDrift, + PseudoVerletLeapfrog, McAte2, Ruth3, McAte3, CandyRoz4, McAte4, McAte42, McAte5, CalvoSanz4, Yoshida6, KahanLi6, McAte8, KahanLi8, SofSpa10 using OrdinaryDiffEqRKN diff --git a/test/downstream/Project.toml b/test/downstream/Project.toml index 6f934b345f..7dd1b77444 100644 --- a/test/downstream/Project.toml +++ b/test/downstream/Project.toml @@ -2,7 +2,7 @@ DDEProblemLibrary = "f42792ee-6ffc-4e2a-ae83-8ee2f22de800" DelayDiffEq = "bcd4f6db-9728-5f36-b5f7-82caef46ccdb" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" -OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" @@ -16,4 +16,4 @@ OrdinaryDiffEq = "6" SciMLSensitivity = "7.30" StaticArrays = "1" StochasticDiffEq = "6.60.1" -Zygote = "0.6.61" +Zygote = "0.6.61, 0.7" diff --git a/test/downstream/autodiff_events.jl b/test/downstream/autodiff_events.jl index 9c2a23c5a0..e8a4a0d9a4 100644 --- a/test/downstream/autodiff_events.jl +++ b/test/downstream/autodiff_events.jl @@ -24,7 +24,7 @@ prob = ODEProblem(f, eltype(p).([1.0, 0.0]), eltype(p).((0.0, 1.0)), copy(p)) function test_f(p) _prob = remake(prob, p = p) solve(_prob, Tsit5(), abstol = 1e-14, reltol = 1e-14, callback = cb, - save_everystep = false).u[end] + save_everystep = false).u[end] end findiff = Calculus.finite_difference_jacobian(test_f, p) findiff diff --git a/test/downstream/delaydiffeq.jl b/test/downstream/delaydiffeq.jl index b68f8144c4..58228780d2 100644 --- a/test/downstream/delaydiffeq.jl +++ b/test/downstream/delaydiffeq.jl @@ -1,4 +1,4 @@ -using DelayDiffEq, DDEProblemLibrary +using DelayDiffEq, DDEProblemLibrary, ADTypes using Test @testset "Constant delays" begin @@ -25,7 +25,7 @@ using Test sol_scalar = solve(prob_scalar, ddealg) @test sol.t≈sol_scalar.t atol=1e-3 - @test sol[1, :] ≈ sol_scalar.u atol=1e-3 + @test sol[1, :]≈sol_scalar.u atol=1e-3 end end @@ -43,4 +43,4 @@ h(p, t) = [1.0, 1.0] h(p, t; idxs = 1) = 1.0 p = [1.5, 1.0, 3.0, 1.0, 1.0] prob = DDEProblem(lotka_volterra!, uₒ, h, tspan, p, constant_lags = (p[end],)) -sol = solve(prob, MethodOfSteps(AutoTsit5(Rosenbrock23(autodiff = false)))) +sol = solve(prob, MethodOfSteps(AutoTsit5(Rosenbrock23(autodiff = AutoFiniteDiff())))) diff --git a/test/gpu/linear_exp.jl b/test/gpu/linear_exp.jl index dbbde584cc..41cb74e5d2 100644 --- a/test/gpu/linear_exp.jl +++ b/test/gpu/linear_exp.jl @@ -8,7 +8,7 @@ using OrdinaryDiffEq A = MatrixOperator([2.0 -1.0; -1.0 2.0]) u0 = ones(2) -A_gpu = MatrixOperator(cu([2.0 -1.0; -1.0 2.0])) +A_gpu = MatrixOperator(cu([2.0 -1.0; -1.0 2.0])) u0_gpu = cu(ones(2)) prob_gpu = ODEProblem(A_gpu, u0_gpu, (0.0, 1.0)) @@ -22,7 +22,7 @@ sol3_gpu = solve(prob_gpu, LinearExponential(krylov = :adaptive))(1.0) |> Vector @test isapprox(sol2_gpu, sol_analytic, rtol = 1e-6) @test isapprox(sol3_gpu, sol_analytic, rtol = 1e-6) -A2_gpu = MatrixOperator(cu(sparse([2.0 -1.0; -1.0 2.0]))) +A2_gpu = MatrixOperator(cu(sparse([2.0 -1.0; -1.0 2.0]))) prob2_gpu = ODEProblem(A2_gpu, u0_gpu, (0.0, 1.0)) @test_broken sol2_1_gpu = solve(prob2_gpu, LinearExponential(krylov = :off))(1.0) |> Vector @@ -31,4 +31,4 @@ sol2_3_gpu = solve(prob2_gpu, LinearExponential(krylov = :adaptive))(1.0) |> Vec @test_broken isapprox(sol2_1_gpu, sol_analytic, rtol = 1e-6) @test isapprox(sol2_2_gpu, sol_analytic, rtol = 1e-6) -@test isapprox(sol2_3_gpu, sol_analytic, rtol = 1e-6) \ No newline at end of file +@test isapprox(sol2_3_gpu, sol_analytic, rtol = 1e-6) diff --git a/test/integrators/check_error.jl b/test/integrators/check_error.jl index dc80ff87fa..61ab159544 100644 --- a/test/integrators/check_error.jl +++ b/test/integrators/check_error.jl @@ -57,5 +57,5 @@ end @test_broken sol.retcode = ReturnCode.Success end -@test_throws ArgumentError solve(prob, Euler(), dt=0.1, adaptive=true) +@test_throws ArgumentError solve(prob, Euler(), dt = 0.1, adaptive = true) @test_throws ArgumentError solve(prob, Euler()) diff --git a/test/integrators/ode_cache_tests.jl b/test/integrators/ode_cache_tests.jl index 8e766a319b..1dc92cbfc0 100644 --- a/test/integrators/ode_cache_tests.jl +++ b/test/integrators/ode_cache_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, OrdinaryDiffEqCore, DiffEqBase, Test +using OrdinaryDiffEq, OrdinaryDiffEqCore, DiffEqBase, Test, ADTypes using Random, SparseDiffTools using OrdinaryDiffEqDefault using ElasticArrays, LinearSolve @@ -79,9 +79,11 @@ for alg in broken_CACHE_TEST_ALGS @test_broken length(solve(prob, alg, callback = callback, dt = 1 / 2)[end]) > 1 end -sol = solve(prob, Rodas4(chunk_size = 1), callback = callback, dt = 1 / 2) +sol = solve(prob, Rodas4(autodiff = AutoForwardDiff(chunksize = 1)), + callback = callback, dt = 1 / 2) @test length(sol[end]) > 1 -sol = solve(prob, Rodas5(chunk_size = 1), callback = callback, dt = 1 / 2) +sol = solve(prob, Rodas5(autodiff = AutoForwardDiff(chunksize = 1)), + callback = callback, dt = 1 / 2) @test length(sol[end]) > 1 # cache tests resizing multidimensional arrays diff --git a/test/integrators/ode_event_tests.jl b/test/integrators/ode_event_tests.jl index 32995814b1..69f0153d5b 100644 --- a/test/integrators/ode_event_tests.jl +++ b/test/integrators/ode_event_tests.jl @@ -411,23 +411,21 @@ step!(integrator, 1e-5, true) @test all(u -> u > 1.5, integrator.u) # https://github.com/SciML/OrdinaryDiffEq.jl/pull/1777 -if VERSION >= v"1.7" - @testset "Callbacks with LinearExponential" begin - A = sprand(ComplexF64, 100, 100, 0.5) - A += A' +@testset "Callbacks with LinearExponential" begin + A = Matrix(sprand(ComplexF64, 100, 100, 0.5)) + A += A' - t_l = LinRange(0, 1, 100) + t_l = LinRange(0, 1, 100) - saved_values = SavedValues(Float64, Float64) - function save_func(u, t, integrator) - real(u' * A * u) - end - cb = SavingCallback(save_func, saved_values, saveat = t_l) - - u0 = normalize(rand(ComplexF64, 100)) - A = MatrixOperator(-1im * A) - prob = ODEProblem(A, u0, (0, 1.0)) - solve(prob, LinearExponential(), dt = t_l[2] - t_l[1], callback = cb) - @test length(saved_values.saveval) == length(t_l) + saved_values = SavedValues(Float64, Float64) + function save_func(u, t, integrator) + real(u' * A * u) end + cb = SavingCallback(save_func, saved_values, saveat = t_l) + + u0 = normalize(rand(ComplexF64, 100)) + A = MatrixOperator(-1im * A) + prob = ODEProblem(A, u0, (0, 1.0)) + solve(prob, LinearExponential(), dt = t_l[2] - t_l[1], callback = cb) + @test length(saved_values.saveval) == length(t_l) end diff --git a/test/integrators/resize_tests.jl b/test/integrators/resize_tests.jl index fb5dc583de..1b2933d1a9 100644 --- a/test/integrators/resize_tests.jl +++ b/test/integrators/resize_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, Test +using OrdinaryDiffEq, Test, ADTypes f(du, u, p, t) = du .= u prob = ODEProblem(f, [1.0], (0.0, 1.0)) @@ -38,7 +38,7 @@ resize!(i, 5) @test length(i.cache.nlsolver.cache.weight) == 5 solve!(i) -i = init(prob, ImplicitEuler(; autodiff = false)) +i = init(prob, ImplicitEuler(; autodiff = AutoFiniteDiff())) resize!(i, 5) @test length(i.cache.atmp) == 5 @test length(i.cache.uprev) == 5 @@ -83,7 +83,7 @@ resize!(i, 5) @test length(i.cache.jac_config.p) == 5 solve!(i) -i = init(prob, Rosenbrock23(; autodiff = false)) +i = init(prob, Rosenbrock23(; autodiff = AutoFiniteDiff())) resize!(i, 5) @test length(i.cache.u) == 5 @test length(i.cache.uprev) == 5 @@ -185,7 +185,7 @@ end runSim(BS3()) runSim(Rosenbrock23()) -runSim(Rosenbrock23(autodiff = false)) +runSim(Rosenbrock23(autodiff = AutoFiniteDiff())) # https://github.com/SciML/OrdinaryDiffEq.jl/issues/1990 @testset "resize! with SplitODEProblem" begin diff --git a/test/integrators/step_limiter_test.jl b/test/integrators/step_limiter_test.jl index 566d5da527..690d36e557 100644 --- a/test/integrators/step_limiter_test.jl +++ b/test/integrators/step_limiter_test.jl @@ -1,4 +1,5 @@ using OrdinaryDiffEq, Test +using OrdinaryDiffEqFIRK: AdaptiveRadau, RadauIIA9, RadauIIA5, RadauIIA3 # define the counting variable const STEP_LIMITER_VAR = Ref(0) @@ -27,7 +28,8 @@ end KenCarp3, KenCarp4, KenCarp5, Kvaerno3, Kvaerno4, Kvaerno5, Rosenbrock23, Rosenbrock32, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, - RadauIIA5, RadauIIA3, SIR54, Alshina2, Alshina3, Heun, Ralston, Midpoint, RK4, + AdaptiveRadau, RadauIIA9, RadauIIA5, RadauIIA3, SIR54, + Alshina2, Alshina3, Heun, Ralston, Midpoint, RK4, OwrenZen3, OwrenZen4, OwrenZen5, BS3, DP5, Tsit5, DP8, TanYam7, TsitPap8, FRK65, PFRK87, BS5, Vern6, Vern7, Vern8, Vern9, QPRK98, SSPRKMSVS43, SSPRKMSVS32, SSPRK432, SSPRK43, diff --git a/test/interface/ad_tests.jl b/test/interface/ad_tests.jl index 1a85c97ad8..276fae2263 100644 --- a/test/interface/ad_tests.jl +++ b/test/interface/ad_tests.jl @@ -1,5 +1,5 @@ using Test -using OrdinaryDiffEq, Calculus, ForwardDiff, FiniteDiff, LinearAlgebra +using OrdinaryDiffEq, Calculus, ForwardDiff, FiniteDiff, LinearAlgebra, ADTypes function f(du, u, p, t) du[1] = -p[1] @@ -205,7 +205,7 @@ of_a = p -> begin prob = ODEProblem(f_a, u0, tspan, p) # sol = solve(prob, Tsit5()) # works # sol = solve(prob, Rodas5(autodiff=false)) # works - sol = solve(prob, Rodas5(autodiff = true), abstol = 1e-14, reltol = 1e-14) # fails + sol = solve(prob, Rodas5(autodiff = AutoForwardDiff()), abstol = 1e-14, reltol = 1e-14) # fails return sum(t -> abs2(t[1]), sol([1.0, 2.0, 3.0])) end @@ -318,3 +318,31 @@ function f(x) end K_ = [-1.0 0.0; 1.0 -1.0] @test isapprox(ForwardDiff.jacobian(f, K_)[2], 0.00226999, atol = 1e-6) + +implicit_algs = [FBDF, + Rosenbrock23, + TRBDF2] + +@testset "deprecated AD keyword arguments still work with $alg" for alg in implicit_algs + f = (du, u, p, t) -> du .= -0.5 * u + alg1 = alg(autodiff = AutoForwardDiff()) + alg2 = alg(autodiff = true) + + alg3 = alg(autodiff = AutoFiniteDiff()) + alg4 = alg(autodiff = false) + + alg5 = alg(autodiff = AutoForwardDiff(chunksize = 5)) + alg6 = alg(autodiff = true, chunk_size = 5) + + alg7 = alg(autodiff = AutoFiniteDiff(fdtype = Val(:central))) + alg8 = alg(autodiff = false, diff_type = Val(:central)) + + alg9 = alg(autodiff = AutoForwardDiff(chunksize = 1)) + alg10 = alg(chunk_size = 1) + + @test OrdinaryDiffEq.alg_autodiff(alg1) == OrdinaryDiffEq.alg_autodiff(alg2) + @test OrdinaryDiffEq.alg_autodiff(alg3) == OrdinaryDiffEq.alg_autodiff(alg4) + @test OrdinaryDiffEq.alg_autodiff(alg5) == OrdinaryDiffEq.alg_autodiff(alg6) + @test OrdinaryDiffEq.alg_autodiff(alg7) == OrdinaryDiffEq.alg_autodiff(alg8) + @test OrdinaryDiffEq.alg_autodiff(alg9) == OrdinaryDiffEq.alg_autodiff(alg10) +end diff --git a/test/interface/aliasing_tests.jl b/test/interface/aliasing_tests.jl new file mode 100644 index 0000000000..83b26a26d8 --- /dev/null +++ b/test/interface/aliasing_tests.jl @@ -0,0 +1,10 @@ +using OrdinaryDiffEq, Test + +import ODEProblemLibrary: prob_ode_linear + +# Test that the old keyword works, and that the new AliasSpecier works. +u0_old_alias_kwarg_sol = solve(prob_ode_linear, Tsit5(), alias_u0 = true) +u0_new_alias_kwarg_sol = solve( + prob_ode_linear, Tsit5(), alias = ODEAliasSpecifier(alias_u0 = true)) + +@test u0_old_alias_kwarg_sol == u0_new_alias_kwarg_sol diff --git a/test/interface/autodiff_error_tests.jl b/test/interface/autodiff_error_tests.jl index 195c7bdab4..5e4bdbd258 100644 --- a/test/interface/autodiff_error_tests.jl +++ b/test/interface/autodiff_error_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, Test +using OrdinaryDiffEq, Test, ADTypes using OrdinaryDiffEqDifferentiation const a = Float64[1.0] @@ -50,13 +50,12 @@ prob = ODEProblem(lorenz2!, u0, tspan) ## https://discourse.julialang.org/t/rodas4-using-dual-number-for-time-with-autodiff-false/98256 for alg in [ - Rosenbrock23(autodiff = false), - Rodas4(autodiff = false), - Rodas5(autodiff = false), - QNDF(autodiff = false), - TRBDF2(autodiff = false), - KenCarp4(autodiff = false), - FBDF(autodiff = false) + Rosenbrock23(autodiff = AutoFiniteDiff()), + Rodas4(autodiff = AutoFiniteDiff()), + Rodas5(autodiff = AutoFiniteDiff()), + QNDF(autodiff = AutoFiniteDiff()), + TRBDF2(autodiff = AutoFiniteDiff()), + KenCarp4(autodiff = AutoFiniteDiff()) ] u = [0.0, 0.0] function f1(u, p, t) diff --git a/test/interface/complex_tests.jl b/test/interface/complex_tests.jl index bf3a154d29..9d9092d71d 100644 --- a/test/interface/complex_tests.jl +++ b/test/interface/complex_tests.jl @@ -2,7 +2,7 @@ using Test using StaticArrays, LinearAlgebra -using OrdinaryDiffEq, DiffEqBase +using OrdinaryDiffEq, DiffEqBase, ADTypes H(t) = -im * (@SMatrix [t 1; 1 -t]) @@ -45,20 +45,20 @@ end @testset "Complex Tests on Implicit Finite Diff Methods. alg=$alg" for alg in implicit ψ0 = [1.0 + 0.0im; 0.0] prob = ODEProblem(fun_inplace, ψ0, (-T, T)) - sol = solve(prob, alg(autodiff = false)) + sol = solve(prob, alg(autodiff = AutoFiniteDiff())) @test norm(sol(T))≈1 atol=1e-2 end @testset "Complex Tests on Implicit Finite Diff Out-of-place Methods. alg=$alg" for alg in implicit ψ0 = [1.0 + 0.0im; 0.0] prob = ODEProblem(fun, ψ0, (-T, T)) - sol = solve(prob, alg(autodiff = false)) + sol = solve(prob, alg(autodiff = AutoFiniteDiff())) @test norm(sol(T))≈1 atol=1e-2 end @testset "Complex Tests on Implicit Finite Diff Out-of-place Methods SArray. alg=$alg" for alg in implicit ψ0 = @SArray [1.0 + 0.0im; 0.0] prob = ODEProblem(fun, ψ0, (-T, T)) - sol = solve(prob, alg(autodiff = false)) + sol = solve(prob, alg(autodiff = AutoFiniteDiff())) @test norm(sol(T))≈1 atol=1e-2 end diff --git a/test/interface/composite_algorithm_test.jl b/test/interface/composite_algorithm_test.jl index 01bedd5953..4bdfc958ff 100644 --- a/test/interface/composite_algorithm_test.jl +++ b/test/interface/composite_algorithm_test.jl @@ -1,6 +1,6 @@ using OrdinaryDiffEq, OrdinaryDiffEqCore, Test, LinearAlgebra import ODEProblemLibrary: prob_ode_linear, prob_ode_2Dlinear -using DiffEqDevTools +using DiffEqDevTools, ADTypes prob = prob_ode_2Dlinear choice_function(integrator) = (Int(integrator.t < 0.5) + 1) @@ -49,9 +49,9 @@ v = @inferred OrdinaryDiffEqCore.ode_extrapolant( @test_throws ArgumentError solve(prob_ode_linear, alg_mixed) sol2 = solve(prob_ode_linear, Tsit5()) - sol3 = solve(prob_ode_linear, alg_mixed; dt = 0.05, adaptive=false) - sol4 = solve(prob_ode_linear, alg_mixed_r; dt = 0.05, adaptive=false) - sol5 = solve(prob_ode_linear, alg_mixed2; dt = 0.05, adaptive=false) + sol3 = solve(prob_ode_linear, alg_mixed; dt = 0.05, adaptive = false) + sol4 = solve(prob_ode_linear, alg_mixed_r; dt = 0.05, adaptive = false) + sol5 = solve(prob_ode_linear, alg_mixed2; dt = 0.05, adaptive = false) @test sol3.t == sol4.t && sol3.u == sol4.u @test sol3(0.8)≈sol2(0.8) atol=1e-4 @test sol5(0.8)≈sol2(0.8) atol=1e-4 @@ -78,7 +78,7 @@ sol = solve(prob, @test sol.t[end] == 1000.0 prob = remake(prob_ode_2Dlinear, u0 = rand(ComplexF64, 2, 2)) -sol = solve(prob, AutoTsit5(Rosenbrock23(autodiff = false))) # Complex and AD don't mix +sol = solve(prob, AutoTsit5(Rosenbrock23(autodiff = AutoFiniteDiff()))) # Complex and AD don't mix @test sol.retcode == ReturnCode.Success # https://github.com/SciML/ModelingToolkit.jl/issues/3043 diff --git a/test/interface/dae_initialization_tests.jl b/test/interface/dae_initialization_tests.jl index e00d8270e5..3657f461f3 100644 --- a/test/interface/dae_initialization_tests.jl +++ b/test/interface/dae_initialization_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, StaticArrays, LinearAlgebra, Test +using OrdinaryDiffEq, StaticArrays, LinearAlgebra, Test, ADTypes ## Mass Matrix @@ -15,7 +15,8 @@ M = [1.0 0 0 0 0 0] f_oop = ODEFunction(rober_oop, mass_matrix = M) prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rosenbrock23(autodiff = false), reltol = 1e-8, abstol = 1e-8) +sol = solve( + prob_mm, Rosenbrock23(autodiff = AutoFiniteDiff()), reltol = 1e-8, abstol = 1e-8) @test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8, initializealg = ShampineCollocationInit()) @@ -25,7 +26,7 @@ prob_mm = ODEProblem(f_oop, [1.0, 0.0, 0.2], (0.0, 1e5), (0.04, 3e7, 1e4)) sol = solve(prob_mm, Rosenbrock23(), reltol = 1e-8, abstol = 1e-8) @test sum(sol[1]) ≈ 1 @test sol[1] ≈ [1.0, 0.0, 0.0] -for alg in [Rosenbrock23(autodiff = false), Trapezoid()] +for alg in [Rosenbrock23(autodiff = AutoFiniteDiff()), Trapezoid()] local sol sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, initializealg = ShampineCollocationInit()) @@ -45,7 +46,7 @@ M = [1.0 0 0 0 0 0] f = ODEFunction(rober, mass_matrix = M) prob_mm = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) -sol = solve(prob_mm, Rodas5(autodiff = false), reltol = 1e-8, abstol = 1e-8) +sol = solve(prob_mm, Rodas5(autodiff = AutoFiniteDiff()), reltol = 1e-8, abstol = 1e-8) @test sol[1] == [1.0, 0.0, 0.0] # Ensure initialization is unchanged if it works at the start! sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8, initializealg = ShampineCollocationInit()) @@ -56,7 +57,7 @@ sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8) @test sum(sol[1]) ≈ 1 @test sol[1] ≈ [1.0, 0.0, 0.0] -for alg in [Rodas5(autodiff = false), Trapezoid()] +for alg in [Rodas5(autodiff = AutoFiniteDiff()), Trapezoid()] local sol sol = solve(prob_mm, alg, reltol = 1e-8, abstol = 1e-8, initializealg = ShampineCollocationInit()) diff --git a/test/interface/differentiation_traits_tests.jl b/test/interface/differentiation_traits_tests.jl index d2c3c51d38..75742eb88e 100644 --- a/test/interface/differentiation_traits_tests.jl +++ b/test/interface/differentiation_traits_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, Test +using OrdinaryDiffEq, Test, ADTypes jac_called = Ref(false) tgrad_called = Ref(false) @@ -35,11 +35,11 @@ good_sol = solve(prob, Rosenbrock23()) prob2 = ODEProblem(Lotka, ones(2), (0.0, 10.0)) -sol = solve(prob2, Rosenbrock23(autodiff = true)) +sol = solve(prob2, Rosenbrock23(autodiff = AutoForwardDiff())) @test ≈(good_sol[:, end], sol[:, end], rtol = 1e-2) -sol = solve(prob2, Rosenbrock23(autodiff = true, chunk_size = 1)) +sol = solve(prob2, Rosenbrock23(autodiff = AutoForwardDiff(chunksize = 1))) @test ≈(good_sol[:, end], sol[:, end], rtol = 1e-2) -sol = solve(prob2, Rosenbrock23(autodiff = false)) +sol = solve(prob2, Rosenbrock23(autodiff = AutoFiniteDiff())) @test ≈(good_sol[:, end], sol[:, end], rtol = 1e-2) diff --git a/test/interface/jacobian_tests.jl b/test/interface/jacobian_tests.jl index d23d29d642..3b3bb0c248 100644 --- a/test/interface/jacobian_tests.jl +++ b/test/interface/jacobian_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, ForwardDiff, Test +using OrdinaryDiffEq, ForwardDiff, Test, ADTypes function d_alembert(du, u, p, t) du[1] = p[1] - p[2] * u[1] + p[3] * t @@ -86,7 +86,7 @@ function rober(du, u, p, t) nothing end prob1 = ODEProblem(rober, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4, true)) -sol1 = solve(prob1, TRBDF2(chunk_size = chunksize)) +sol1 = solve(prob1, TRBDF2(autodiff = AutoForwardDiff(chunksize = chunksize))) prob = ODEProblem(rober, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4, false)) sol = solve(prob, TRBDF2()) @test sol.u[end] == sol1.u[end] diff --git a/test/interface/linear_nonlinear_tests.jl b/test/interface/linear_nonlinear_tests.jl index b948996346..6930d59b4c 100644 --- a/test/interface/linear_nonlinear_tests.jl +++ b/test/interface/linear_nonlinear_tests.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, Test, Random, LinearAlgebra, LinearSolve +using OrdinaryDiffEq, Test, Random, LinearAlgebra, LinearSolve, ADTypes Random.seed!(123) A = 0.01 * rand(3, 3) @@ -35,70 +35,71 @@ function precslr(W, du, u, p, t, newW, Plprev, Prprev, solverdata) Pr, Pr end -sol = @test_nowarn solve(prob, TRBDF2(autodiff = false)); +sol = @test_nowarn solve(prob, TRBDF2(autodiff = AutoFiniteDiff())); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES())); + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES())); @test length(sol.t) < 20 solref = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), smooth_est = false)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precsl, smooth_est = false, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precsr, smooth_est = false, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precslr, smooth_est = false, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - QNDF(autodiff = false, linsolve = KrylovJL_GMRES(), + QNDF(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), concrete_jac = true)); @test length(sol.t) < 25 sol = @test_nowarn solve(prob, - Rosenbrock23(autodiff = false, + Rosenbrock23(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precslr, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - Rodas4(autodiff = false, linsolve = KrylovJL_GMRES(), + Rodas4(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precslr, concrete_jac = true)); @test length(sol.t) < 20 -sol = @test_nowarn solve(prob, TRBDF2(autodiff = false)); +sol = @test_nowarn solve(prob, TRBDF2(autodiff = AutoFiniteDiff())); @test length(sol.t) < 20 -sol = @test_nowarn solve(prob, TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES())); +sol = @test_nowarn solve( + prob, TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES())); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), smooth_est = false)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precsl, smooth_est = false, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precsr, smooth_est = false, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - TRBDF2(autodiff = false, linsolve = KrylovJL_GMRES(), + TRBDF2(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precslr, smooth_est = false, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - QNDF(autodiff = false, linsolve = KrylovJL_GMRES(), + QNDF(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), concrete_jac = true)); @test length(sol.t) < 25 sol = @test_nowarn solve(prob, - Rosenbrock23(autodiff = false, linsolve = KrylovJL_GMRES(), + Rosenbrock23(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precslr, concrete_jac = true)); @test length(sol.t) < 20 sol = @test_nowarn solve(prob, - Rodas4(autodiff = false, linsolve = KrylovJL_GMRES(), + Rodas4(autodiff = AutoFiniteDiff(), linsolve = KrylovJL_GMRES(), precs = precslr, concrete_jac = true)); @test length(sol.t) < 20 diff --git a/test/interface/nojac.jl b/test/interface/nojac.jl index 9a252ddfea..6f0229a4f0 100644 --- a/test/interface/nojac.jl +++ b/test/interface/nojac.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, LinearSolve, Test +using OrdinaryDiffEq, LinearSolve, Test, ADTypes const N = 32 const xyd_brusselator = range(0, stop = 1, length = N) @@ -253,6 +253,7 @@ integ = init(prob, Rosenbrock23(linsolve = SimpleLUFactorization()), abstol = 1e integ = init(prob, Rosenbrock23(linsolve = GenericLUFactorization()), abstol = 1e-6, reltol = 1e-6) @test integ.cache.jac_config === nothing -integ = init(prob, Rosenbrock23(linsolve = RFLUFactorization(), chunk_size = Val{3}()), +integ = init(prob, + Rosenbrock23(linsolve = RFLUFactorization(), autodiff = AutoForwardDiff(chunksize = 3)), abstol = 1e-6, reltol = 1e-6) @test integ.cache.jac_config === nothing diff --git a/test/interface/norecompile.jl b/test/interface/norecompile.jl index 4eee7b9e6e..989031de95 100644 --- a/test/interface/norecompile.jl +++ b/test/interface/norecompile.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, Test +using OrdinaryDiffEq, Test, ADTypes function f(du, u, p, t) du[1] = 0.2u[1] du[2] = 0.4u[2] @@ -15,13 +15,13 @@ end lorenzprob = ODEProblem(lorenz, [1.0; 0.0; 0.0], (0.0, 1.0), Float64[]) t1 = @elapsed sol1 = solve(lorenzprob, Rosenbrock23()) -t2 = @elapsed sol2 = solve(lorenzprob, Rosenbrock23(autodiff = false)) +t2 = @elapsed sol2 = solve(lorenzprob, Rosenbrock23(autodiff = AutoFiniteDiff())) lorenzprob2 = ODEProblem{true, SciMLBase.FullSpecialize}(lorenz, [1.0; 0.0; 0.0], (0.0, 1.0), Float64[]) t3 = @elapsed sol3 = solve(lorenzprob2, Rosenbrock23()) -t4 = @elapsed sol4 = solve(lorenzprob2, Rosenbrock23(autodiff = false)) +t4 = @elapsed sol4 = solve(lorenzprob2, Rosenbrock23(autodiff = AutoFiniteDiff())) @test sol1.retcode === ReturnCode.Success @test sol2.retcode === ReturnCode.Success diff --git a/test/interface/ode_initdt_tests.jl b/test/interface/ode_initdt_tests.jl index 2045e4874d..2bee803e1e 100644 --- a/test/interface/ode_initdt_tests.jl +++ b/test/interface/ode_initdt_tests.jl @@ -66,7 +66,7 @@ prob = ODEProblem((u, p, t) -> 1e20 * sin(1e20 * t), 0.1, (0, 1e-19)) @test solve(prob, Tsit5()).retcode == ReturnCode.Success #test that we are robust to u0=0, t0!=0 -integ = init(ODEProblem(((u,p,t)->u), 0f0, (20f0, 0f0)), Tsit5()) +integ = init(ODEProblem(((u, p, t) -> u), 0.0f0, (20.0f0, 0.0f0)), Tsit5()) @test abs(integ.dt) > eps(integ.t) -integ = init(ODEProblem(((du,u,p,t)->du.=u), [0f0], (20f0, 0f0)), Tsit5()) +integ = init(ODEProblem(((du, u, p, t) -> du .= u), [0.0f0], (20.0f0, 0.0f0)), Tsit5()) @test abs(integ.dt) > eps(integ.t) diff --git a/test/interface/ode_strip_test.jl b/test/interface/ode_strip_test.jl index f30a4492aa..697332da2d 100644 --- a/test/interface/ode_strip_test.jl +++ b/test/interface/ode_strip_test.jl @@ -43,7 +43,6 @@ end @testset "Default Solution Stripping" begin stripped_sol = SciMLBase.strip_solution(default_sol) @test isnothing(stripped_sol.interp.cache.args) - end @test_throws SciMLBase.LazyInterpolationException SciMLBase.strip_solution(vern_sol) diff --git a/test/interface/precision_mixing.jl b/test/interface/precision_mixing.jl index 497944d65d..727025c3e0 100644 --- a/test/interface/precision_mixing.jl +++ b/test/interface/precision_mixing.jl @@ -2,7 +2,7 @@ using OrdinaryDiffEq function ODE(du, u, t, R, K) du .= u end -params = BigFloat[1. 0.91758707304098; 1.48439909482661 1.] +params = BigFloat[1.0 0.91758707304098; 1.48439909482661 1.0] u0 = BigFloat[0.1, 0.1] tspan = (1.0, 31.0) R = BigFloat[0.443280390004304303, 1.172917082211452] @@ -16,7 +16,6 @@ for alg in [AutoVern8(Rodas5(), nonstifftol = 11 / 10) Rodas5P() TRBDF2() KenCarp4() - RadauIIA5() - ] + RadauIIA5()] Solution = solve(odeProblem, alg, saveat = 1, abstol = 1.e-12, reltol = 1.e-6) -end \ No newline at end of file +end diff --git a/test/interface/scalar_handling_tests.jl b/test/interface/scalar_handling_tests.jl index f7103a5d9a..c9d20773a0 100644 --- a/test/interface/scalar_handling_tests.jl +++ b/test/interface/scalar_handling_tests.jl @@ -1,4 +1,5 @@ -using OrdinaryDiffEq +using OrdinaryDiffEq, ADTypes # https://github.com/JuliaDiffEq/DifferentialEquations.jl/issues/390 -solve(ODEProblem((x, p, t) -> -x, 1.0, (0.0, 50.0)), Rosenbrock23(autodiff = false)) +solve(ODEProblem((x, p, t) -> -x, 1.0, (0.0, 50.0)), + Rosenbrock23(autodiff = AutoFiniteDiff())) diff --git a/test/interface/sparsediff_tests.jl b/test/interface/sparsediff_tests.jl index 63983ade09..10304b5b57 100644 --- a/test/interface/sparsediff_tests.jl +++ b/test/interface/sparsediff_tests.jl @@ -2,6 +2,7 @@ using Test using OrdinaryDiffEq using SparseArrays using LinearAlgebra +using ADTypes ## in-place #https://github.com/JuliaDiffEq/SparseDiffTools.jl/blob/master/test/test_integration.jl @@ -51,7 +52,7 @@ for f in [f_oop, f_ip] odefun_std = ODEFunction(f) prob_std = ODEProblem(odefun_std, u0, tspan) - for ad in [true, false] + for ad in [AutoForwardDiff(), AutoFiniteDiff()] for Solver in [Rodas5, Rosenbrock23, Trapezoid, KenCarp4] for tol in [nothing, 1e-10] sol_std = solve(prob_std, Solver(autodiff = ad), reltol = tol, abstol = tol) diff --git a/test/interface/static_array_tests.jl b/test/interface/static_array_tests.jl index 5849de74bd..c4ba0d8fdf 100644 --- a/test/interface/static_array_tests.jl +++ b/test/interface/static_array_tests.jl @@ -1,6 +1,6 @@ using StaticArrays, Test using OrdinaryDiffEq, OrdinaryDiffEqCore, OrdinaryDiffEqNonlinearSolve -using RecursiveArrayTools +using RecursiveArrayTools, ADTypes u0 = VectorOfArray([fill(2, MVector{2, Float64}), ones(MVector{2, Float64})]) g0(u, p, t) = SA[u[1] + u[2], u[1]] @@ -58,7 +58,7 @@ end u0 = @SVector [1.0, 0.0, 0.0] tspan = (0.0, 100.0) prob = ODEProblem(lorenz_static, u0, tspan) -solve(prob, dt = 0.1, Rosenbrock23(autodiff = false)) +solve(prob, dt = 0.1, Rosenbrock23(autodiff = AutoFiniteDiff())) # Check that ArrayPartitions of static vectors work #https://github.com/SciML/OrdinaryDiffEq.jl/issues/1308 @@ -94,8 +94,10 @@ function rober(u, p, t) end prob = ODEProblem{false}(rober, SA[1.0, 0.0, 0.0], (0.0, 1e5), SA[0.04, 3e7, 1e4]) # Defaults to reltol=1e-3, abstol=1e-6 -@test_nowarn sol = solve(prob, Rosenbrock23(chunk_size = Val{3}()), save_everystep = false) -@test_nowarn sol = solve(prob, Rodas4(chunk_size = Val{3}()), save_everystep = false) +@test_nowarn sol = solve( + prob, Rosenbrock23(autodiff = AutoForwardDiff(chunksize = 3)), save_everystep = false) +@test_nowarn sol = solve( + prob, Rodas4(autodiff = AutoForwardDiff(chunksize = 3)), save_everystep = false) function hires_4(u, p, t) y1, y2, y3, y4 = u @@ -109,8 +111,10 @@ end u0 = SA[1, 0, 0, 0.0057] prob = ODEProblem(hires_4, u0, (0.0, 321.8122)) # Defaults to reltol=1e-3, abstol=1e-6 -@test_nowarn sol = solve(prob, Rosenbrock23(chunk_size = Val{4}()), save_everystep = false) -@test_nowarn sol = solve(prob, Rodas5(chunk_size = Val{4}()), save_everystep = false) +@test_nowarn sol = solve( + prob, Rosenbrock23(autodiff = AutoForwardDiff(chunksize = 4)), save_everystep = false) +@test_nowarn sol = solve( + prob, Rodas5(autodiff = AutoForwardDiff(chunksize = 4)), save_everystep = false) function hires_5(u, p, t) y1, y2, y3, y4, y5 = u @@ -125,8 +129,10 @@ end u0 = SA[1, 0, 0, 0, 0.0057] prob = ODEProblem(hires_5, u0, (0.0, 321.8122)) # Defaults to reltol=1e-3, abstol=1e-6 -@test_nowarn sol = solve(prob, Rosenbrock23(chunk_size = Val{5}()), save_everystep = false) -@test_nowarn sol = solve(prob, Rodas4(chunk_size = Val{5}()), save_everystep = false) +@test_nowarn sol = solve( + prob, Rosenbrock23(autodiff = AutoForwardDiff(chunksize = 5)), save_everystep = false) +@test_nowarn sol = solve( + prob, Rodas4(autodiff = AutoForwardDiff(chunksize = 5)), save_everystep = false) function hires(u, p, t) y1, y2, y3, y4, y5, y6, y7, y8 = u @@ -145,8 +151,10 @@ end u0 = SA[1, 0, 0, 0, 0, 0, 0, 0.0057] prob = ODEProblem(hires, u0, (0.0, 321.8122)) # Defaults to reltol=1e-3, abstol=1e-6 -@test_nowarn sol = solve(prob, Rosenbrock23(chunk_size = Val{8}()), save_everystep = false) -@test_nowarn sol = solve(prob, Rodas5(chunk_size = Val{8}()), save_everystep = false) +@test_nowarn sol = solve( + prob, Rosenbrock23(autodiff = AutoForwardDiff(chunksize = 8)), save_everystep = false) +@test_nowarn sol = solve( + prob, Rodas5(autodiff = AutoForwardDiff(chunksize = 8)), save_everystep = false) const k1 = 0.35e0 const k2 = 0.266e2 @@ -235,8 +243,10 @@ u0[9] = 0.01 u0[17] = 0.007 u0 = SA[u0...] prob = ODEProblem(pollu, u0, (0.0, 60.0)) -@test_nowarn sol = solve(prob, Rosenbrock23(chunk_size = Val{8}()), save_everystep = false) -@test_nowarn sol = solve(prob, Rodas5(chunk_size = Val{8}()), save_everystep = false) +@test_nowarn sol = solve( + prob, Rosenbrock23(autodiff = AutoForwardDiff(chunksize = 8)), save_everystep = false) +@test_nowarn sol = solve( + prob, Rodas5(autodiff = AutoForwardDiff(chunksize = 8)), save_everystep = false) # DFBDF g1(du, u, p, t) = du .^ 2 - conj.(u) @@ -261,11 +271,11 @@ du0 = SA[-0.5051593302918506 - 0.87178524227302im, -0.5011616766671037 + 0.8651123244481334im, -0.5065728050401669 + 0.8738635859036186im] prob = DAEProblem(g1, du0, u0, (0.0, 10.0)) -sol1 = solve(prob, DFBDF(autodiff = false), reltol = 1e-8, abstol = 1e-8) +sol1 = solve(prob, DFBDF(autodiff = AutoFiniteDiff()), reltol = 1e-8, abstol = 1e-8) g2(resid, du, u, p, t) = resid .= du .^ 2 - conj.(u) prob = DAEProblem(g2, Array(du0), Array(u0), (0.0, 10.0)) -sol2 = solve(prob, DFBDF(autodiff = false), reltol = 1e-8, abstol = 1e-8) +sol2 = solve(prob, DFBDF(autodiff = AutoFiniteDiff()), reltol = 1e-8, abstol = 1e-8) @test all(iszero, sol1[:, 1] - sol2[:, 1]) @test all(abs.(sol1[:, end] .- sol2[:, end]) .< 1.5e-6) diff --git a/test/interface/stats_tests.jl b/test/interface/stats_tests.jl index 13f06cb127..2c5bf18285 100644 --- a/test/interface/stats_tests.jl +++ b/test/interface/stats_tests.jl @@ -1,5 +1,5 @@ # stats.nf tests -using OrdinaryDiffEq, Test +using OrdinaryDiffEq, Test, ADTypes x = Ref(0) function f(u, p, t) x[] += 1 @@ -23,12 +23,12 @@ probip = ODEProblem(g, u0, tspan) @test x[] == sol.stats.nf end @testset "$alg" for alg in [Rodas5P, KenCarp4] - @testset "$kwargs" for kwargs in [(autodiff = true,), - (autodiff = false, diff_type = Val{:forward}), - (autodiff = false, diff_type = Val{:central}), - (autodiff = false, diff_type = Val{:complex}),] + @testset "$kwargs" for kwargs in [(autodiff = AutoForwardDiff(),), + (autodiff = AutoFiniteDiff(fdtype = Val{:forward}()),), + (autodiff = AutoFiniteDiff(fdtype = Val{:central}()),), + (autodiff = AutoFiniteDiff(fdtype = Val{:complex}()),)] x[] = 0 - sol = solve(prob, alg(;kwargs...)) + sol = solve(prob, alg(; kwargs...)) @test x[] == sol.stats.nf end end diff --git a/test/interface/stiffness_detection_test.jl b/test/interface/stiffness_detection_test.jl index 4ae725c460..503f0bb7a9 100644 --- a/test/interface/stiffness_detection_test.jl +++ b/test/interface/stiffness_detection_test.jl @@ -1,4 +1,4 @@ -using OrdinaryDiffEq, Test +using OrdinaryDiffEq, Test, ADTypes import ODEProblemLibrary: van using ForwardDiff: Dual @@ -20,14 +20,14 @@ probArr = [prob1, prob2, prob3] for prob in [prob2, prob3], u0 in [prob.u0, Dual.(prob.u0, prob.u0)] prob′ = remake(prob3, u0 = u0) - @test_nowarn solve(prob′, AutoTsit5(Rosenbrock23(autodiff = false))) + @test_nowarn solve(prob′, AutoTsit5(Rosenbrock23(autodiff = AutoFiniteDiff()))) end # Test if switching back and forth is_switching_fb(sol) = all(i -> count(isequal(i), sol.alg_choice[2:end]) > 5, (1, 2)) for (i, prob) in enumerate(probArr) println(i) - sol = @test_nowarn solve(prob, AutoTsit5(Rosenbrock23(autodiff = false)), + sol = @test_nowarn solve(prob, AutoTsit5(Rosenbrock23(autodiff = AutoFiniteDiff())), maxiters = 1000) @test is_switching_fb(sol) alg = AutoTsit5(Rodas5(); maxstiffstep = 5, maxnonstiffstep = 5, stiffalgfirst = true) @@ -61,7 +61,7 @@ for (i, prob) in enumerate(probArr) @test length(sol.t) < 570 @test is_switching_fb(sol) sol = solve(prob, - AutoVern9(KenCarp3(autodiff = false); maxstiffstep = 4, + AutoVern9(KenCarp3(autodiff = AutoFiniteDiff()); maxstiffstep = 4, maxnonstiffstep = 1), maxiters = 1000) @test length(sol.t) < 570 @test is_switching_fb(sol) diff --git a/test/interface/units_tests.jl b/test/interface/units_tests.jl index 280116dba2..cad23ebc91 100644 --- a/test/interface/units_tests.jl +++ b/test/interface/units_tests.jl @@ -1,5 +1,5 @@ using OrdinaryDiffEq, RecursiveArrayTools, Unitful -using LinearAlgebra, Test +using LinearAlgebra, Test, ADTypes @testset "Algorithms" begin algs = [ @@ -55,10 +55,10 @@ end sol = solve(prob, alg) end - for alg in [AutoVern6(Rodas5(autodiff = false)), - AutoVern7(Rodas5(autodiff = false)), - AutoVern8(Rodas5(autodiff = false)), - AutoVern9(Rodas5(autodiff = false))] + for alg in [AutoVern6(Rodas5(autodiff = AutoFiniteDiff())), + AutoVern7(Rodas5(autodiff = AutoFiniteDiff())), + AutoVern8(Rodas5(autodiff = AutoFiniteDiff())), + AutoVern9(Rodas5(autodiff = AutoFiniteDiff()))] @show alg @test_broken sol = solve(prob, alg) end diff --git a/test/interface/utility_tests.jl b/test/interface/utility_tests.jl index 2a8ba62c8f..a8a5628ab6 100644 --- a/test/interface/utility_tests.jl +++ b/test/interface/utility_tests.jl @@ -10,7 +10,7 @@ using OrdinaryDiffEq.OrdinaryDiffEqDifferentiation: WOperator, calc_W, calc_W!, tspan = (0.0, 1.0) dt = 0.01 dtgamma = 0.5dt - concrete_W = A - inv(dtgamma)*mm + concrete_W = A - inv(dtgamma) * mm # Out-of-place fun = ODEFunction((u, p, t) -> A * u; diff --git a/test/multithreading/ode_extrapolation_tests.jl b/test/multithreading/ode_extrapolation_tests.jl index 765471eb9e..ae157b0222 100644 --- a/test/multithreading/ode_extrapolation_tests.jl +++ b/test/multithreading/ode_extrapolation_tests.jl @@ -1,6 +1,8 @@ # Import packages using OrdinaryDiffEqExtrapolation, DiffEqDevTools, Test, Random +println("Running on $(Threads.nthreads()) thread(s).") + # Define test problems # Note that the time span in ODEProblemLibrary is given by # Float64 numbers diff --git a/test/regression/iipvsoop_tests.jl b/test/regression/iipvsoop_tests.jl index e3f2756410..b316f5bb31 100644 --- a/test/regression/iipvsoop_tests.jl +++ b/test/regression/iipvsoop_tests.jl @@ -1,5 +1,5 @@ using OrdinaryDiffEq, Test -using OrdinaryDiffEqCore +using OrdinaryDiffEqCore, ADTypes f(u, p, t) = 0.98u u0 = 1.0 @@ -10,28 +10,35 @@ sol = solve(prob, Tsit5()) # Make sure various differentiation forms work on scalars sol1 = solve(prob, Rosenbrock23(), abstol = 1e-12, reltol = 1e-12) -sol2 = solve(prob, Rosenbrock23(autodiff = false), abstol = 1e-12, reltol = 1e-12) -sol3 = solve(prob, Rosenbrock23(autodiff = false, diff_type = Val{:central}), +sol2 = solve( + prob, Rosenbrock23(autodiff = AutoFiniteDiff()), abstol = 1e-12, reltol = 1e-12) +sol3 = solve(prob, Rosenbrock23(autodiff = AutoFiniteDiff(fdtype = Val(:central))), abstol = 1e-12, reltol = 1e-12) -sol4 = solve(prob, Rosenbrock23(autodiff = false, diff_type = Val{:complex}), +sol4 = solve(prob, Rosenbrock23(autodiff = AutoFiniteDiff(fdtype = Val(:complex))), abstol = 1e-12, reltol = 1e-12) sol5 = solve(prob, KenCarp4(), abstol = 1e-12, reltol = 1e-12) -sol6 = solve(prob, KenCarp4(autodiff = false), abstol = 1e-12, reltol = 1e-12) -sol7 = solve(prob, KenCarp4(autodiff = false, diff_type = Val{:central}), abstol = 1e-12, +sol6 = solve(prob, KenCarp4(autodiff = AutoFiniteDiff()), abstol = 1e-12, reltol = 1e-12) +sol7 = solve( + prob, KenCarp4(autodiff = AutoFiniteDiff(fdtype = Val(:central))), abstol = 1e-12, reltol = 1e-12) -sol8 = solve(prob, KenCarp4(autodiff = false, diff_type = Val{:complex}), abstol = 1e-12, +sol8 = solve( + prob, KenCarp4(autodiff = AutoFiniteDiff(fdtype = Val(:complex))), abstol = 1e-12, reltol = 1e-12) sol9 = solve(prob, KenCarp47(), abstol = 1e-12, reltol = 1e-12) -sol10 = solve(prob, KenCarp47(autodiff = false), abstol = 1e-12, reltol = 1e-12) -sol11 = solve(prob, KenCarp47(autodiff = false, diff_type = Val{:central}), abstol = 1e-12, +sol10 = solve(prob, KenCarp47(autodiff = AutoFiniteDiff()), abstol = 1e-12, reltol = 1e-12) +sol11 = solve( + prob, KenCarp47(autodiff = AutoFiniteDiff(fdtype = Val(:central))), abstol = 1e-12, reltol = 1e-12) -sol12 = solve(prob, KenCarp47(autodiff = false, diff_type = Val{:complex}), abstol = 1e-12, +sol12 = solve( + prob, KenCarp47(autodiff = AutoFiniteDiff(fdtype = Val(:complex))), abstol = 1e-12, reltol = 1e-12) sol13 = solve(prob, KenCarp58(), abstol = 1e-12, reltol = 1e-12) -sol14 = solve(prob, KenCarp58(autodiff = false), abstol = 1e-12, reltol = 1e-12) -sol15 = solve(prob, KenCarp58(autodiff = false, diff_type = Val{:central}), abstol = 1e-12, +sol14 = solve(prob, KenCarp58(autodiff = AutoFiniteDiff()), abstol = 1e-12, reltol = 1e-12) +sol15 = solve( + prob, KenCarp58(autodiff = AutoFiniteDiff(fdtype = Val(:central))), abstol = 1e-12, reltol = 1e-12) -sol16 = solve(prob, KenCarp58(autodiff = false, diff_type = Val{:complex}), abstol = 1e-12, +sol16 = solve( + prob, KenCarp58(autodiff = AutoFiniteDiff(fdtype = Val(:complex))), abstol = 1e-12, reltol = 1e-12) ts = 0.0:0.1:1.0 @@ -87,7 +94,7 @@ end working_sdirk_algs = [ImplicitMidpoint(), ImplicitEuler(), - ImplicitMidpoint(autodiff = false), + ImplicitMidpoint(autodiff = AutoFiniteDiff()), SSPSDIRK2()] sdirk_algs = [Trapezoid(), diff --git a/test/runtests.jl b/test/runtests.jl index 55b58486ab..28b3d74199 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -56,6 +56,7 @@ end @time @safetestset "Inplace Interpolation Tests" include("interface/inplace_interpolation.jl") @time @safetestset "Algebraic Interpolation Tests" include("interface/algebraic_interpolation.jl") @time @safetestset "Interpolation and Cache Stripping Tests" include("interface/ode_strip_test.jl") + @time @safetestset "Aliasing Tests" include("interface/aliasing_tests.jl") end if !is_APPVEYOR && (GROUP == "All" || GROUP == "InterfaceII" || GROUP == "Interface")