@@ -368,15 +368,22 @@ to avoid divisions by zero.
368368 Applied Numerical Mathematics 182 (2022): 117-147.
369369 [DOI: 10.1016/j.apnum.2022.07.014](https://doi.org/10.1016/j.apnum.2022.07.014)
370370"""
371- struct MPRK22{T, F} <: OrdinaryDiffEqAdaptiveAlgorithm
371+ struct MPRK22{T, F, T2 } <: OrdinaryDiffEqAdaptiveAlgorithm
372372 alpha:: T
373373 linsolve:: F
374- small_constant :: T
374+ small_constant_function :: T2
375375end
376376
377377function MPRK22 (alpha; linsolve = LUFactorization (),
378- small_constant = floatmin (typeof (alpha)))
379- MPRK22 {typeof(alpha), typeof(linsolve)} (alpha, linsolve, small_constant)
378+ small_constant = nothing )
379+ if isnothing (small_constant)
380+ small_constant_function = floatmin
381+ elseif small_constant isa Number
382+ small_constant_function = Returns (small_constant)
383+ else # assume small_constant isa Function
384+ small_constant_function = small_constant
385+ end
386+ MPRK22 {typeof(alpha), typeof(linsolve)} (alpha, linsolve, small_constant_function)
380387end
381388
382389alg_order (:: MPRK22 ) = 2
@@ -415,8 +422,7 @@ function alg_cache(alg::MPRK22, u, rate_prototype, ::Type{uEltypeNoUnits},
415422 end
416423
417424 a21, b1, b2 = get_constant_parameters (alg)
418- small_constant = alg. small_constant
419- MPRK22ConstantCache (a21, b1, b2, small_constant)
425+ MPRK22ConstantCache (a21, b1, b2, alg. small_constant_function (uEltypeNoUnits))
420426end
421427
422428function initialize! (integrator, cache:: MPRK22ConstantCache )
@@ -525,8 +531,7 @@ function alg_cache(alg::MPRK22, u, rate_prototype, ::Type{uEltypeNoUnits},
525531 uprev, uprev2, f, t, dt, reltol, p, calck,
526532 :: Val{true} ) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits}
527533 a21, b1, b2 = get_constant_parameters (alg)
528- small_constant = alg. small_constant
529- tab = MPRK22ConstantCache (a21, b1, b2, small_constant)
534+ tab = MPRK22ConstantCache (a21, b1, b2, alg. small_constant_function (uEltypeNoUnits))
530535 tmp = zero (u)
531536 P = p_prototype (u, f)
532537 # We use P2 to store the last evaluation of the PDS
@@ -732,16 +737,23 @@ to avoid divisions by zero.
732737 BIT Numerical Mathematics 58 (2018): 691–728.
733738 [DOI: 10.1007/s10543-018-0705-1](https://doi.org/10.1007/s10543-018-0705-1)
734739"""
735- struct MPRK43I{T, F} <: OrdinaryDiffEqAdaptiveAlgorithm
740+ struct MPRK43I{T, F, T2 } <: OrdinaryDiffEqAdaptiveAlgorithm
736741 alpha:: T
737742 beta:: T
738743 linsolve:: F
739- small_constant :: T
744+ small_constant_function :: T2
740745end
741746
742747function MPRK43I (alpha, beta; linsolve = LUFactorization (),
743- small_constant = floatmin (typeof (alpha)))
744- MPRK43I {typeof(alpha), typeof(linsolve)} (alpha, beta, linsolve, small_constant)
748+ small_constant = nothing )
749+ if isnothing (small_constant)
750+ small_constant_function = floatmin
751+ elseif small_constant isa Number
752+ small_constant_function = Returns (small_constant)
753+ else # assume small_constant isa Function
754+ small_constant_function = small_constant
755+ end
756+ MPRK43I {typeof(alpha), typeof(linsolve)} (alpha, beta, linsolve, small_constant_function)
745757end
746758
747759alg_order (:: MPRK43I ) = 3
@@ -822,14 +834,21 @@ to avoid divisions by zero.
822834 BIT Numerical Mathematics 58 (2018): 691–728.
823835 [DOI: 10.1007/s10543-018-0705-1](https://doi.org/10.1007/s10543-018-0705-1)
824836"""
825- struct MPRK43II{T, F} <: OrdinaryDiffEqAdaptiveAlgorithm
837+ struct MPRK43II{T, F, T2 } <: OrdinaryDiffEqAdaptiveAlgorithm
826838 gamma:: T
827839 linsolve:: F
828- small_constant :: T
840+ small_constant_function :: T2
829841end
830842
831- function MPRK43II (gamma; linsolve = LUFactorization (), small_constant = floatmin ())
832- MPRK43II {typeof(gamma), typeof(linsolve)} (gamma, linsolve, small_constant)
843+ function MPRK43II (gamma; linsolve = LUFactorization (), small_constant = nothing )
844+ if isnothing (small_constant)
845+ small_constant_function = floatmin
846+ elseif small_constant isa Number
847+ small_constant_function = Returns (small_constant)
848+ else # assume small_constant isa Function
849+ small_constant_function = small_constant
850+ end
851+ MPRK43II {typeof(gamma), typeof(linsolve)} (gamma, linsolve, small_constant_function)
833852end
834853
835854alg_order (:: MPRK43II ) = 3
@@ -887,9 +906,8 @@ function alg_cache(alg::Union{MPRK43I, MPRK43II}, u, rate_prototype, ::Type{uElt
887906 throw (ArgumentError (" MPRK43 can only be applied to production-destruction systems" ))
888907 end
889908 a21, a31, a32, b1, b2, b3, c2, c3, beta1, beta2, q1, q2 = get_constant_parameters (alg)
890- small_constant = alg. small_constant
891909 MPRK43ConstantCache (a21, a31, a32, b1, b2, b3, c2, c3,
892- beta1, beta2, q1, q2, small_constant )
910+ beta1, beta2, q1, q2, alg . small_constant_function (uEltypeNoUnits) )
893911end
894912
895913function initialize! (integrator, cache:: MPRK43ConstantCache )
@@ -1046,9 +1064,9 @@ function alg_cache(alg::Union{MPRK43I, MPRK43II}, u, rate_prototype, ::Type{uElt
10461064 uprev, uprev2, f, t, dt, reltol, p, calck,
10471065 :: Val{true} ) where {uEltypeNoUnits, uBottomEltypeNoUnits, tTypeNoUnits}
10481066 a21, a31, a32, b1, b2, b3, c2, c3, beta1, beta2, q1, q2 = get_constant_parameters (alg)
1049- small_constant = alg. small_constant
10501067 tab = MPRK43ConstantCache (a21, a31, a32, b1, b2, b3, c2, c3,
1051- beta1, beta2, q1, q2, small_constant)
1068+ beta1, beta2, q1, q2,
1069+ alg. small_constant_function (uEltypeNoUnits))
10521070 tmp = zero (u)
10531071 tmp2 = zero (u)
10541072 P = p_prototype (u, f)
0 commit comments