1+ EnumX. @enumx DefaultSolverChoice begin
2+ Tsit5 = 1
3+ Vern7 = 2
4+ Rosenbrock23 = 3
5+ Rodas5P = 4
6+ FBDF = 5
7+ KrylovFBDF = 6
8+ end
9+
10+ const NUM_NONSTIFF = 2
11+ const NUM_STIFF = 4
12+ const LOW_TOL = 1e-6
13+ const MED_TOL = 1e-2
14+ const EXTREME_TOL = 1e-9
15+ const SMALLSIZE = 50
16+ const MEDIUMSIZE = 500
17+ const STABILITY_SIZES = (alg_stability_size (Tsit5 ()), alg_stability_size (Vern7 ()))
18+ const DEFAULTBETA2S = (
19+ beta2_default (Tsit5 ()), beta2_default (Vern7 ()), beta2_default (Rosenbrock23 ()),
20+ beta2_default (Rodas5P ()), beta2_default (FBDF ()), beta2_default (FBDF ()))
21+ const DEFAULTBETA1S = (
22+ beta1_default (Tsit5 (), DEFAULTBETA2S[1 ]), beta1_default (Vern7 (), DEFAULTBETA2S[2 ]),
23+ beta1_default (Rosenbrock23 (), DEFAULTBETA2S[3 ]), beta1_default (
24+ Rodas5P (), DEFAULTBETA2S[4 ]),
25+ beta1_default (FBDF (), DEFAULTBETA2S[5 ]), beta1_default (FBDF (), DEFAULTBETA2S[6 ]))
26+
27+ callbacks_exists (integrator) = ! isempty (integrator. opts. callbacks)
28+ current_nonstiff (current) = ifelse (current <= NUM_NONSTIFF, current, current - NUM_STIFF)
29+
30+ function DefaultODEAlgorithm (; lazy = true , stiffalgfirst = false , kwargs... )
31+ nonstiff = (Tsit5 (), Vern7 (lazy = lazy))
32+ stiff = (Rosenbrock23 (; kwargs... ), Rodas5P (; kwargs... ), FBDF (; kwargs... ),
33+ FBDF (; linsolve = LinearSolve. KrylovJL_GMRES (), kwargs... ))
34+ AutoAlgSwitch (nonstiff, stiff; stiffalgfirst)
35+ end
36+
37+ function is_stiff (integrator, alg, ntol, stol, is_stiffalg, current)
38+ eigen_est, dt = integrator. eigen_est, integrator. dt
39+ stiffness = abs (eigen_est * dt /
40+ STABILITY_SIZES[nonstiffchoice (integrator. opts. reltol)]) # `abs` here is just for safety
41+ tol = is_stiffalg ? stol : ntol
42+ os = oneunit (stiffness)
43+ bool = stiffness > os * tol
44+
45+ if ! bool
46+ integrator. alg. choice_function. successive_switches += 1
47+ else
48+ integrator. alg. choice_function. successive_switches = 0
49+ end
50+
51+ integrator. do_error_check = (integrator. alg. choice_function. successive_switches >
52+ integrator. alg. choice_function. switch_max || ! bool) ||
53+ is_stiffalg
54+ bool
55+ end
56+
57+ function nonstiffchoice (reltol)
58+ x = if reltol < LOW_TOL
59+ DefaultSolverChoice. Vern7
60+ else
61+ DefaultSolverChoice. Tsit5
62+ end
63+ Int (x)
64+ end
65+
66+ function stiffchoice (reltol, len, mass_matrix)
67+ x = if len > MEDIUMSIZE
68+ DefaultSolverChoice. KrylovFBDF
69+ elseif len > SMALLSIZE
70+ DefaultSolverChoice. FBDF
71+ else
72+ if reltol < LOW_TOL || ! isdiag (mass_matrix)
73+ DefaultSolverChoice. Rodas5P
74+ else
75+ DefaultSolverChoice. Rosenbrock23
76+ end
77+ end
78+ Int (x)
79+ end
80+
81+ function default_autoswitch (AS:: AutoSwitchCache , integrator)
82+ len = length (integrator. u)
83+ reltol = integrator. opts. reltol
84+
85+ # Choose the starting method
86+ if AS. current == 0
87+ choice = if AS. stiffalgfirst || integrator. f. mass_matrix != I
88+ stiffchoice (reltol, len, integrator. f. mass_matrix)
89+ else
90+ nonstiffchoice (reltol)
91+ end
92+ AS. current = choice
93+ return AS. current
94+ end
95+
96+ dt = integrator. dt
97+ # Successive stiffness test positives are counted by a positive integer,
98+ # and successive stiffness test negatives are counted by a negative integer
99+ AS. count = is_stiff (integrator, AS. nonstiffalg, AS. nonstifftol, AS. stifftol,
100+ AS. is_stiffalg, AS. current) ?
101+ AS. count < 0 ? 1 : AS. count + 1 :
102+ AS. count > 0 ? - 1 : AS. count - 1
103+ if integrator. f. mass_matrix != I
104+ # don't change anything
105+ elseif (! AS. is_stiffalg && AS. count > AS. maxstiffstep)
106+ integrator. dt = dt * AS. dtfac
107+ AS. is_stiffalg = true
108+ AS. current = stiffchoice (reltol, len, integrator. f. mass_matrix)
109+ elseif (AS. is_stiffalg && AS. count < - AS. maxnonstiffstep)
110+ integrator. dt = dt / AS. dtfac
111+ AS. is_stiffalg = false
112+ AS. current = nonstiffchoice (reltol)
113+ end
114+ return AS. current
115+ end
116+
117+ # hack for the default alg
118+ function is_mass_matrix_alg (alg:: CompositeAlgorithm {
119+ <: Any , <: Tuple{Tsit5, Vern7, Rosenbrock23, Rodas5P, FBDF, FBDF} })
120+ true
121+ end
0 commit comments