Skip to content

Commit b74059b

Browse files
committed
All SSPMPRK schemes internally use small_constant_function
1 parent d5c38a7 commit b74059b

1 file changed

Lines changed: 32 additions & 16 deletions

File tree

src/sspmprk.jl

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
### SSPMPRK #####################################################################################
22
"""
3-
SSPMPRK22(α, β; [linsolve = ...])
3+
SSPMPRK22(α, β; [linsolve = ..., small_constant = ...])
44
55
A family of second-order modified Patankar-Runge-Kutta algorithms for
66
production-destruction systems. Each member of this family is a one-step, two-stage method which is
@@ -36,16 +36,25 @@ to avoid divisions by zero.
3636
ESAIM: Mathematical Modelling and Numerical Analysis 57 (2023):1063–1086
3737
[DOI: 10.1051/m2an/2023005](https://doi.org/10.1051/m2an/2023005)
3838
"""
39-
struct SSPMPRK22{T, F} <: OrdinaryDiffEqAdaptiveAlgorithm
39+
struct SSPMPRK22{T, F, T2} <: OrdinaryDiffEqAdaptiveAlgorithm
4040
alpha::T
4141
beta::T
4242
linsolve::F
43-
small_constant::T
43+
small_constant_function::T2
4444
end
4545

4646
function SSPMPRK22(alpha, beta; linsolve = LUFactorization(),
47-
small_constant = floatmin(alpha))
48-
SSPMPRK22{typeof(alpha), typeof(linsolve)}(alpha, beta, linsolve, small_constant)
47+
small_constant = nothing)
48+
if isnothing(small_constant)
49+
small_constant_function = floatmin
50+
elseif small_constant isa Number
51+
small_constant_function = Returns(small_constant)
52+
else # assume small_constant isa Function
53+
small_constant_function = small_constant
54+
end
55+
SSPMPRK22{typeof(alpha), typeof(linsolve), typeof(small_constant_function)}(alpha, beta,
56+
linsolve,
57+
small_constant_function)
4958
end
5059

5160
alg_order(::SSPMPRK22) = 2
@@ -95,8 +104,8 @@ function alg_cache(alg::SSPMPRK22, u, rate_prototype, ::Type{uEltypeNoUnits},
95104
end
96105

97106
a21, a10, a20, b10, b20, b21, s = get_constant_parameters(alg)
98-
small_constant = alg.small_constant
99-
SSPMPRK22ConstantCache(a21, a10, a20, b10, b20, b21, s, small_constant)
107+
SSPMPRK22ConstantCache(a21, a10, a20, b10, b20, b21, s,
108+
alg.small_constant_function(uEltypeNoUnits))
100109
end
101110

102111
function initialize!(integrator, cache::SSPMPRK22ConstantCache)
@@ -204,8 +213,8 @@ function alg_cache(alg::SSPMPRK22, u, rate_prototype, ::Type{uEltypeNoUnits},
204213
uprev, uprev2, f, t, dt, reltol, p, calck,
205214
::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits}
206215
a21, a10, a20, b10, b20, b21, s = get_constant_parameters(alg)
207-
small_constant = alg.small_constant
208-
tab = SSPMPRK22ConstantCache(a21, a10, a20, b10, b20, b21, s, small_constant)
216+
tab = SSPMPRK22ConstantCache(a21, a10, a20, b10, b20, b21, s,
217+
alg.small_constant_function(uEltypeNoUnits))
209218
tmp = zero(u)
210219
P = p_prototype(u, f)
211220
# We use P2 to store the last evaluation of the PDS
@@ -378,7 +387,7 @@ function perform_step!(integrator, cache::SSPMPRK22ConservativeCache, repeat_ste
378387
end
379388

380389
"""
381-
SSPMPRK43([linsolve = ...])
390+
SSPMPRK43([linsolve = ..., small_constant = ...])
382391
383392
A third-order modified Patankar-Runge-Kutta algorithm for
384393
production-destruction systems. This scheme is a one-step, two-stage method which is
@@ -415,11 +424,19 @@ to avoid divisions by zero.
415424
"""
416425
struct SSPMPRK43{F, T} <: OrdinaryDiffEqAlgorithm
417426
linsolve::F
418-
small_constant::T
427+
small_constant_function::T
419428
end
420429

421430
function SSPMPRK43(; linsolve = LUFactorization(), small_constant = 1e-50)
422-
SSPMPRK43{typeof(linsolve), typeof(small_constant)}(linsolve, small_constant)
431+
if isnothing(small_constant)
432+
small_constant_function = floatmin
433+
elseif small_constant isa Number
434+
small_constant_function = Returns(small_constant)
435+
else # assume small_constant isa Function
436+
small_constant_function = small_constant
437+
end
438+
SSPMPRK43{typeof(linsolve), typeof(small_constant_function)}(linsolve,
439+
small_constant_function)
423440
end
424441

425442
alg_order(::SSPMPRK43) = 3
@@ -496,11 +513,10 @@ function alg_cache(alg::SSPMPRK43, u, rate_prototype, ::Type{uEltypeNoUnits},
496513
throw(ArgumentError("SSPMPRK43 can only be applied to production-destruction systems"))
497514
end
498515
n1, n2, z, η1, η2, η3, η4, η5, η6, s, α10, α20, α21, α30, α31, α32, β10, β20, β21, β30, β31, β32, c3 = get_constant_parameters(alg)
499-
small_constant = alg.small_constant
500516
SSPMPRK43ConstantCache(n1, n2, z, η1, η2, η3, η4, η5, η6, s, α10, α20, α21, α30, α31,
501517
α32, β10,
502518
β20, β21, β30,
503-
β31, β32, c3, small_constant)
519+
β31, β32, c3, alg.small_constant_function(uEltypeNoUnits))
504520
end
505521

506522
function initialize!(integrator, cache::SSPMPRK43ConstantCache)
@@ -662,10 +678,10 @@ function alg_cache(alg::SSPMPRK43, u, rate_prototype, ::Type{uEltypeNoUnits},
662678
uprev, uprev2, f, t, dt, reltol, p, calck,
663679
::Val{true}) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits}
664680
n1, n2, z, η1, η2, η3, η4, η5, η6, s, α10, α20, α21, α30, α31, α32, β10, β20, β21, β30, β31, β32, c3 = get_constant_parameters(alg)
665-
small_constant = alg.small_constant
666681
tab = SSPMPRK43ConstantCache(n1, n2, z, η1, η2, η3, η4, η5, η6, s, α10, α20, α21, α30,
667682
α31, α32,
668-
β10, β20, β21, β30, β31, β32, c3, small_constant)
683+
β10, β20, β21, β30, β31, β32, c3,
684+
alg.small_constant_function(uEltypeNoUnits))
669685
tmp = zero(u)
670686
tmp2 = zero(u)
671687
P = p_prototype(u, f)

0 commit comments

Comments
 (0)