Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added FineRKN5 Algorithm #1948

Merged
merged 20 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
de350a3
Caches, Documentation and all relevant information for a new Nystrom5…
HenryLangner May 18, 2023
216cec0
Merge branch 'SciML:master' into master
HenryLangner May 18, 2023
fa44553
Added tableau structure for Nystrom5, values not yet added
HenryLangner May 23, 2023
d6bc336
Merge remote-tracking branch 'refs/remotes/origin/master'
HenryLangner May 23, 2023
5d25936
Perform_set and tableau for Nystrom5 added. Nystrom5 is working on in…
HenryLangner May 26, 2023
ad7dd23
Used JuliaFormatter
HenryLangner May 26, 2023
b7747fb
Cleaned up the Butcher Table for Nystrom5 und changed to perform_step…
HenryLangner May 26, 2023
c7c1a89
Nystrom5 is now FineRKN5. Using rational tableau only with FineRKN5
HenryLangner May 28, 2023
13669a6
Changed Nystrom5 to FineRKN5
HenryLangner May 28, 2023
c06063e
Added convergence tests for
HenryLangner May 30, 2023
5a9ca94
Merge branch 'SciML:master' into master
HenryLangner May 30, 2023
b187d0d
Added missing out of olace convergence test for ```FineRKN5```.
HenryLangner May 30, 2023
d132868
Update src/algorithms.jl
HenryLangner Jun 1, 2023
22b2b7c
Update src/algorithms.jl
HenryLangner Jun 1, 2023
4a27a6e
Update src/algorithms.jl
HenryLangner Jun 1, 2023
6e4a431
Update src/algorithms.jl
HenryLangner Jun 1, 2023
23c8bf4
Added ```FineRKN5``` to ```docs/src/dynamical/nystrom.m```.
HenryLangner Jun 1, 2023
0c30db2
Merge branch 'SciML:master' into master
HenryLangner Jun 6, 2023
548178c
Merge branch 'master' into master
ChrisRackauckas Jun 7, 2023
419d07a
Update src/algorithms.jl
ChrisRackauckas Jun 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/dynamical/nystrom.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ IRKN3
Nystrom4
Nystrom4VelocityIndependent
IRKN4
FineRKN5
Nystrom5VelocityIndependent
DPRKN6
DPRKN8
Expand Down
2 changes: 1 addition & 1 deletion src/OrdinaryDiffEq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ export SymplecticEuler, VelocityVerlet, VerletLeapfrog, PseudoVerletLeapfrog,

export SplitEuler

export Nystrom4, Nystrom4VelocityIndependent, Nystrom5VelocityIndependent,
export Nystrom4, FineRKN5, Nystrom4VelocityIndependent, Nystrom5VelocityIndependent,
IRKN3, IRKN4, DPRKN4, DPRKN5, DPRKN6, DPRKN6FM, DPRKN8, DPRKN12, ERKN4, ERKN5, ERKN7

export ROCK2, ROCK4, RKC, IRKC, ESERK4, ESERK5, SERK2
Expand Down
1 change: 1 addition & 0 deletions src/alg_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ alg_order(alg::SofSpa10) = 10

alg_order(alg::IRKN3) = 3
alg_order(alg::Nystrom4) = 4
alg_order(alg::FineRKN5) = 5
alg_order(alg::Nystrom4VelocityIndependent) = 4
alg_order(alg::IRKN4) = 4
alg_order(alg::Nystrom5VelocityIndependent) = 5
Expand Down
25 changes: 25 additions & 0 deletions src/algorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5251,6 +5251,31 @@ E. Hairer, S.P. Norsett, G. Wanner, (1993) Solving Ordinary Differential Equatio
"""
struct Nystrom4 <: OrdinaryDiffEqPartitionedAlgorithm end

"""
FineRKN5()

A 5th order explicit Runge-Kutta-Nyström method which can be applied directly to second order ODEs.
Can only be used with fixed time steps.

This method requires that the acceleration equation needs to be independent of the velocity
otherwise it results in convergence order loss.

## References
```
@article{fine1987low,
title={Low order practical {R}unge-{K}utta-{N}ystr{\"o}m methods},
author={Fine, Jerry Michael},
journal={Computing},
volume={38},
number={4},
pages={281--297},
year={1987},
publisher={Springer}
}
```
"""
struct FineRKN5 <: OrdinaryDiffEqPartitionedAlgorithm end

"""
Nystrom4VelocityIdependent

Expand Down
41 changes: 41 additions & 0 deletions src/caches/rkn_caches.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,47 @@ end

# alg_cache(alg::Nystrom4,u,rate_prototype,::Type{uEltypeNoUnits},::Type{uBottomEltypeNoUnits},::Type{tTypeNoUnits},uprev,uprev2,f,t,dt,reltol,p,calck,::Val{false}) where {uEltypeNoUnits,uBottomEltypeNoUnits,tTypeNoUnits} = Nystrom4ConstantCache(constvalue(uBottomEltypeNoUnits),constvalue(tTypeNoUnits))

@cache struct FineRKN5Cache{uType, rateType, reducedRateType, TabType} <:
OrdinaryDiffEqMutableCache
u::uType
uprev::uType
fsalfirst::rateType
k2::reducedRateType
k3::reducedRateType
k4::reducedRateType
k5::reducedRateType
k6::reducedRateType
k7::reducedRateType
k::rateType
tmp::uType
tab::TabType
end

function alg_cache(alg::FineRKN5, u, rate_prototype, ::Type{uEltypeNoUnits},
::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t,
dt, reltol, p, calck,
::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits}
reduced_rate_prototype = rate_prototype.x[2]
tab = FineRKN5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits))
k1 = zero(rate_prototype)
k2 = zero(reduced_rate_prototype)
k3 = zero(reduced_rate_prototype)
k4 = zero(reduced_rate_prototype)
k5 = zero(reduced_rate_prototype)
k6 = zero(reduced_rate_prototype)
k7 = zero(reduced_rate_prototype)
k = zero(rate_prototype)
tmp = zero(u)
FineRKN5Cache(u, uprev, k1, k2, k3, k4, k5, k6, k7, k, tmp, tab)
end

function alg_cache(alg::FineRKN5, u, rate_prototype, ::Type{uEltypeNoUnits},
::Type{uBottomEltypeNoUnits}, ::Type{tTypeNoUnits}, uprev, uprev2, f, t,
dt, reltol, p, calck,
::Val{false}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits}
FineRKN5ConstantCache(constvalue(uBottomEltypeNoUnits), constvalue(tTypeNoUnits))
end

@cache struct Nystrom4VelocityIndependentCache{uType, rateType, reducedRateType} <:
OrdinaryDiffEqMutableCache
u::uType
Expand Down
139 changes: 123 additions & 16 deletions src/perform_step/rkn_perform_step.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
## y₁ = y₀ + hy'₀ + h²∑b̄ᵢk'ᵢ
## y'₁ = y'₀ + h∑bᵢk'ᵢ

const NystromCCDefaultInitialization = Union{Nystrom4ConstantCache,
Nystrom4VelocityIndependentConstantCache,
Nystrom5VelocityIndependentConstantCache,
IRKN3ConstantCache, IRKN4ConstantCache,
DPRKN4ConstantCache, DPRKN5ConstantCache,
DPRKN6FMConstantCache, DPRKN8ConstantCache,
DPRKN12ConstantCache, ERKN4ConstantCache,
ERKN5ConstantCache, ERKN7ConstantCache}
const NystromCCDefaultInitialization = Union{Nystrom4ConstantCache, FineRKN5ConstantCache,
Nystrom4VelocityIndependentConstantCache,
Nystrom5VelocityIndependentConstantCache,
IRKN3ConstantCache, IRKN4ConstantCache,
DPRKN4ConstantCache, DPRKN5ConstantCache,
DPRKN6FMConstantCache, DPRKN8ConstantCache,
DPRKN12ConstantCache, ERKN4ConstantCache,
ERKN5ConstantCache, ERKN7ConstantCache}

function initialize!(integrator, cache::NystromCCDefaultInitialization)
integrator.kshortsize = 2
Expand All @@ -25,14 +25,14 @@ function initialize!(integrator, cache::NystromCCDefaultInitialization)
integrator.fsalfirst = ArrayPartition((kdu, ku))
end

const NystromDefaultInitialization = Union{Nystrom4Cache,
Nystrom4VelocityIndependentCache,
Nystrom5VelocityIndependentCache,
IRKN3Cache, IRKN4Cache,
DPRKN4Cache, DPRKN5Cache,
DPRKN6FMCache, DPRKN8Cache,
DPRKN12Cache, ERKN4Cache,
ERKN5Cache, ERKN7Cache}
const NystromDefaultInitialization = Union{Nystrom4Cache, FineRKN5Cache,
Nystrom4VelocityIndependentCache,
Nystrom5VelocityIndependentCache,
IRKN3Cache, IRKN4Cache,
DPRKN4Cache, DPRKN5Cache,
DPRKN6FMCache, DPRKN8Cache,
DPRKN12Cache, ERKN4Cache,
ERKN5Cache, ERKN7Cache}

function initialize!(integrator, cache::NystromDefaultInitialization)
@unpack fsalfirst, k = cache
Expand Down Expand Up @@ -122,6 +122,113 @@ end
integrator.stats.nf2 += 1
end

@muladd function perform_step!(integrator, cache::FineRKN5ConstantCache,
repeat_step = false)
@unpack t, dt, f, p = integrator
duprev, uprev = integrator.uprev.x
@unpack c1, c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a52, a53, a54, a61, a62, a63, a64, a71, a73, a74, a75, abar21, abar31, abar32, abar41, abar42, abar43, abar51, abar52, abar53, abar54, abar61, abar62, abar63, abar64, abar65, abar71, abar73, abar74, abar75, abar76, b1, b3, b4, b5, bbar1, bbar3, bbar4, bbar5, bbar6 = cache
k1 = integrator.fsalfirst.x[1]

ku = uprev + (c2 * dt * duprev) + (dt^2 * a21 * k1)
kdu = duprev + dt * (abar21 * k1)

k2 = f.f1(kdu, ku, p, t + dt * c2)
ku = uprev + dt * (c3 * duprev + dt * (a31 * k1 + a32 * k2))
kdu = duprev + dt * (abar31 * k1 + abar32 * k2)

k3 = f.f1(kdu, ku, p, t + dt * c3)
ku = uprev + dt * (c4 * duprev + dt * (a41 * k1 + a43 * k3)) # a42 = 0
kdu = duprev + dt * (abar41 * k1 + abar42 * k2 + abar43 * k3)

k4 = f.f1(kdu, ku, p, t + dt * c4)
ku = uprev + dt * (c5 * duprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4))
kdu = duprev + dt * (abar51 * k1 + abar52 * k2 + abar53 * k3 + abar54 * k4)

k5 = f.f1(duprev, ku, p, t + dt * c5)
ku = uprev +
dt * (c6 * duprev + dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4)) # a65 = 0
kdu = duprev +
dt * (abar61 * k1 + abar62 * k2 + abar63 * k3 + abar64 * k4 + abar65 * k5)

k6 = f.f1(duprev, ku, p, t + dt * c6)
ku = uprev +
dt * (c7 * duprev +
dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5)) # a72 = a76 = 0
kdu = duprev +
dt * (abar71 * k1 + abar73 * k3 + abar74 * k4 + abar75 * k5 +
abar76 * k6) # abar72 = 0

k7 = f.f1(duprev, ku, p, t + dt * c7)
u = uprev + dt * (duprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5)) # no b6, b7
du = duprev + dt * (bbar1 * k1 + bbar3 * k3 + bbar4 * k4 + bbar5 * k5 + bbar6 * k6) # no b2, b7

integrator.u = ArrayPartition((du, u))
integrator.fsallast = ArrayPartition((f.f1(du, u, p, t + dt), f.f2(du, u, p, t + dt)))
integrator.stats.nf += 4
integrator.stats.nf2 += 1
integrator.k[1] = integrator.fsalfirst
integrator.k[2] = integrator.fsallast
end

@muladd function perform_step!(integrator, cache::FineRKN5Cache, repeat_step = false)
@unpack t, dt, f, p = integrator
du, u = integrator.u.x
duprev, uprev = integrator.uprev.x
@unpack tmp, fsalfirst, k2, k3, k4, k5, k6, k7, k = cache
@unpack c2, c3, c4, c5, c6, c7, a21, a31, a32, a41, a43, a51, a52, a53, a54, a61, a62, a63, a64, a71, a73, a74, a75, abar21, abar31, abar32, abar41, abar42, abar43, abar51, abar52, abar53, abar54, abar61, abar62, abar63, abar64, abar65, abar71, abar73, abar74, abar75, abar76, b1, b3, b4, b5, bbar1, bbar3, bbar4, bbar5, bbar6 = cache.tab

kdu, ku = integrator.cache.tmp.x[1], integrator.cache.tmp.x[2]
k1 = integrator.fsalfirst.x[1]

@.. broadcast=false ku=uprev + dt * (c2 * duprev + dt * (a21 * k1))
@.. broadcast=false kdu=duprev + dt * (abar21 * k1)

f.f1(k2, kdu, ku, p, t + dt * c2)
@.. broadcast=false ku=uprev + dt * (c3 * duprev + dt * (a31 * k1 + a32 * k2))
@.. broadcast=false kdu=duprev + dt * (abar31 * k1 + abar32 * k2)

f.f1(k3, kdu, ku, p, t + dt * c3)
@.. broadcast=false ku=uprev +
dt * (c4 * duprev + dt * (a41 * k1 + a43 * k3)) # a42 = 0
@.. broadcast=false kdu=duprev + dt * (abar41 * k1 + abar42 * k2 + abar43 * k3)

f.f1(k4, kdu, ku, p, t + dt * c4)
@.. broadcast=false ku=uprev +
dt *
(c5 * duprev + dt * (a51 * k1 + a52 * k2 + a53 * k3 + a54 * k4))
@.. broadcast=false kdu=duprev +
dt * (abar51 * k1 + abar52 * k2 + abar53 * k3 + abar54 * k4)

f.f1(k5, kdu, ku, p, t + dt * c5)
@.. broadcast=false ku=uprev +
dt * (c6 * duprev +
dt * (a61 * k1 + a62 * k2 + a63 * k3 + a64 * k4)) # a65 = 0
@.. broadcast=false kdu=duprev +
dt * (abar61 * k1 + abar62 * k2 + abar63 * k3 + abar64 * k4 +
abar65 * k5)

f.f1(k6, kdu, ku, p, t + dt * c6)
@.. broadcast=false ku=uprev +
dt * (c7 * duprev +
dt * (a71 * k1 + a73 * k3 + a74 * k4 + a75 * k5)) # a72 = a76 = 0

@.. broadcast=false kdu=duprev +
dt * (abar71 * k1 + abar73 * k3 + abar74 * k4 +
abar75 * k5 + abar76 * k6) # abar72 = 0

f.f1(k7, kdu, ku, p, t + dt * c7)
@.. broadcast=false u=uprev +
dt * (duprev + dt * (b1 * k1 + b3 * k3 + b4 * k4 + b5 * k5))
@.. broadcast=false du=duprev +
dt *
(bbar1 * k1 + bbar3 * k3 + bbar4 * k4 + bbar5 * k5 + bbar6 * k6)

f.f1(k.x[1], du, u, p, t + dt)
f.f2(k.x[2], du, u, p, t + dt)
integrator.stats.nf += 1
integrator.stats.nf2 += 1
end

@muladd function perform_step!(integrator, cache::Nystrom4VelocityIndependentConstantCache,
repeat_step = false)
@unpack t, dt, f, p = integrator
Expand Down
Loading